Browse Source

Copy across the copy task and strip out filtering

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271238 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
d408d99390
2 changed files with 481 additions and 0 deletions
  1. +466
    -0
      proposal/myrmidon/src/java/org/apache/antlib/file/CopyTask.java
  2. +15
    -0
      proposal/myrmidon/src/java/org/apache/antlib/file/Resources.properties

+ 466
- 0
proposal/myrmidon/src/java/org/apache/antlib/file/CopyTask.java View File

@@ -0,0 +1,466 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.antlib.file;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.avalon.excalibur.i18n.ResourceManager;
import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.excalibur.io.FileUtil;
import org.apache.myrmidon.api.AbstractTask;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.ScannerUtil;
import org.apache.tools.ant.types.SourceFileScanner;
import org.apache.tools.ant.util.mappers.FileNameMapper;
import org.apache.tools.ant.util.mappers.FlatFileNameMapper;
import org.apache.tools.ant.util.mappers.IdentityMapper;
import org.apache.tools.ant.util.mappers.Mapper;

/**
* This is a task used to copy files.
*
* @ant:task name="copy"
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <A href="gholam@xtra.co.nz">Michael McCallum</A>
* @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a>
* @version $Revision$ $Date$
*/
public class CopyTask
extends AbstractTask
{
private final static Resources REZ =
ResourceManager.getPackageResources( CopyTask.class );

private File m_file;
private ArrayList m_filesets = new ArrayList();
private File m_destFile;
private File m_destDir;
private boolean m_preserveLastModified;
private boolean m_overwrite;
private boolean m_flatten;
private boolean m_includeEmpty = true;
private Mapper m_mapper;

private HashMap m_fileMap = new HashMap();
private HashMap m_dirMap = new HashMap();

/**
* Sets a single source file to copy.
*/
public void setFile( final File file )
{
m_file = file;
}

public void addFileset( final FileSet set )
{
m_filesets.add( set );
}

public void setDestFile( final File destFile )
{
m_destFile = destFile;
}

public void setDestDir( final File destDir )
{
m_destDir = destDir;
}

public void setPreserveLastModified( boolean preserveLastModified )
{
m_preserveLastModified = preserveLastModified;
}

/**
* Overwrite any existing destination file(s).
*/
public void setOverwrite( boolean overwrite )
{
m_overwrite = overwrite;
}

/**
* When copying directory trees, the files can be "flattened" into a single
* directory. If there are multiple files with the same name in the source
* directory tree, only the first file will be copied into the "flattened"
* directory, unless the forceoverwrite attribute is true.
*
* @param flatten The new Flatten value
*/
public void setFlatten( final boolean flatten )
{
m_flatten = flatten;
}

/**
* Defines the FileNameMapper to use (nested mapper element).
*/
public void addMapper( final Mapper mapper )
throws TaskException
{
if( null != m_mapper )
{
final String message = "Cannot define more than one mapper";
throw new TaskException( message );
}
m_mapper = mapper;
}

public void execute()
throws TaskException
{
validate();

// deal with the single file
if( m_file != null )
{
if( null == m_destFile )
{
m_destFile = new File( m_destDir, m_file.getName() );
}

if( m_overwrite ||
( m_file.lastModified() > m_destFile.lastModified() ) )
{
m_fileMap.put( m_file.getAbsolutePath(), m_destFile.getAbsolutePath() );
}
else
{
final String message =
REZ.getString( "copy.omit-uptodate.notice", m_file, m_destFile );
getLogger().debug( message );
}
}

// deal with the filesets
final int size = m_filesets.size();
for( int i = 0; i < size; i++ )
{
final FileSet fileSet = (FileSet)m_filesets.get( i );
final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
final File fromDir = fileSet.getDir();

final String[] srcFiles = scanner.getIncludedFiles();
final String[] srcDirs = scanner.getIncludedDirectories();

scan( fromDir, m_destDir, srcFiles, srcDirs );
}

// do all the copy operations now...
doFileOperations( m_fileMap, m_dirMap );
}

protected void validate()
throws TaskException
{
final int fileSetSize = m_filesets.size();

if( null == m_file && 0 == fileSetSize )
{
final String message = REZ.getString( "copy.missing-src.error" );
throw new TaskException( message );
}

if( null != m_destFile && null != m_destDir )
{
final String message = REZ.getString( "copy.one-dest-only.error" );
throw new TaskException( message );
}

if( null != m_file && m_file.exists() && m_file.isDirectory() )
{
final String message = REZ.getString( "copy.fileset-for-dirs.error" );
throw new TaskException( message );
}

if( null != m_destFile && fileSetSize > 0 )
{
if( fileSetSize > 1 )
{
final String message = REZ.getString( "copy.need-destdir.error" );
throw new TaskException( message );
}
else
{
final FileSet fileSet = (FileSet)m_filesets.get( 0 );
final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet );
final String[] srcFiles = scanner.getIncludedFiles();

if( srcFiles.length > 0 )
{
if( m_file == null )
{
m_file = new File( srcFiles[ 0 ] );
m_filesets.remove( 0 );
}
else
{
final String message = REZ.getString( "copy.bad-mapping.error" );
throw new TaskException( message );
}
}
else
{
final String message = REZ.getString( "copy.bad-operation.error" );
throw new TaskException( message );
}
}
}

if( null != m_file && !m_file.exists() )
{
final String message =
REZ.getString( "copy.missing-file.error", m_file.getAbsolutePath() );
throw new TaskException( message );
}

if( null != m_destFile )
{
m_destDir = m_destFile.getParentFile();
}
}

/**
* Compares source files to destination files to see if they should be
* copied.
*/
private void scan( final File sourceDir,
final File destDir,
final String[] files,
final String[] dirs )
throws TaskException
{
final FileNameMapper mapper = getFilenameMapper();

buildMap( sourceDir, destDir, files, mapper, m_fileMap );

if( m_includeEmpty )
{
buildMap( sourceDir, destDir, dirs, mapper, m_dirMap );
}
}

private void buildMap( final File sourceDir,
final File destDir,
final String[] files,
final FileNameMapper mapper,
final Map map )
throws TaskException
{
final String[] toCopy = buildFilenameList( files, mapper, sourceDir, destDir );
for( int i = 0; i < toCopy.length; i++ )
{
final String destFilename = mapper.mapFileName( toCopy[ i ] )[ 0 ];
final File source = new File( sourceDir, toCopy[ i ] );
final File destination = new File( destDir, destFilename );
map.put( source.getAbsolutePath(), destination.getAbsolutePath() );
}
}

/**
* Utility method to build up a list of files needed between both
* but only getting the files that need updating (unless overwrite is true).
*/
private String[] buildFilenameList( final String[] names,
final FileNameMapper mapper,
final File fromDir,
final File toDir )
throws TaskException
{
if( m_overwrite )
{
final ArrayList list = new ArrayList( names.length );
for( int i = 0; i < names.length; i++ )
{
final String name = names[ i ];
if( null != mapper.mapFileName( name ) )
{
list.add( name );
}
}

return (String[])list.toArray( new String[ list.size() ] );
}
else
{
final SourceFileScanner scanner = new SourceFileScanner();
setupLogger( scanner );
return scanner.restrict( names, fromDir, toDir, mapper );
}
}

/**
* Perform the oepration on all the files (and possibly empty directorys).
*/
private void doFileOperations( final Map fileCopyMap, final Map dirCopyMap )
throws TaskException
{
final int fileCount = fileCopyMap.size();
if( fileCount > 0 )
{
doOperationOnFiles( fileCopyMap );
}

if( m_includeEmpty )
{
doOperationOnDirs( dirCopyMap );
}
}

/**
* perform operation on files.
*/
private void doOperationOnFiles( final Map fileMap )
throws TaskException
{
final int fileCount = fileMap.size();
displayFilecountNotice( fileCount );

final Iterator names = fileMap.keySet().iterator();
while( names.hasNext() )
{
final String source = (String)names.next();
final String destination = (String)fileMap.get( source );

if( source.equals( destination ) )
{
final String message =
REZ.getString( "copy.selfcopy-ignored.notice", source );
getLogger().info( message );
continue;
}

try
{
final String message =
REZ.getString( "copy.filecopy.notice", source, destination );
getLogger().info( message );

doOperation( source, destination );
}
catch( final IOException ioe )
{
final String message =
REZ.getString( "copy.filecopy.error", source, destination, ioe );
throw new TaskException( message, ioe );
}
}
}

/**
* perform operation on directories.
*/
private void doOperationOnDirs( final Map dirMap )
{
final Iterator dirs = dirMap.values().iterator();
int count = 0;
while( dirs.hasNext() )
{
final String pathname = (String)dirs.next();
final File dir = new File( pathname );
if( !dir.exists() )
{
if( !dir.mkdirs() )
{
final String message =
REZ.getString( "copy.dircopy.error", dir.getAbsolutePath() );
getLogger().error( message );
}
else
{
count++;
}
}
}

if( count > 0 )
{
displayDirCopyNotice( count );
}
}

/**
* Utility method to determine and retrieve FilenameMapper.
*/
private FileNameMapper getFilenameMapper()
throws TaskException
{
if( null != m_mapper )
{
return m_mapper.getImplementation();
}
else if( m_flatten )
{
return new FlatFileNameMapper();
}
else
{
return new IdentityMapper();
}
}

/**
* Utility method to perform operation to transform a single source file
* to a destination.
*/
private void doOperation( final String sourceFilename,
final String destinationFilename )
throws IOException
{
final File source = new File( sourceFilename );
final File destination = new File( destinationFilename );

if( m_overwrite )
{
FileUtil.forceDelete( destination );
}

FileUtil.copyFile( source, destination );

if( m_preserveLastModified )
{
destination.setLastModified( source.lastModified() );
}
}

/**
* Utility method to display notice about how many dirs copied.
*/
private void displayDirCopyNotice( final int count )
{
final String message =
REZ.getString( "copy.dir-count.notice",
new Integer( count ),
m_destDir.getAbsolutePath() );
getLogger().info( message );
}

/**
* Utility method to display notice about how many files copied.
*/
private void displayFilecountNotice( final int count )
{
if( getLogger().isInfoEnabled() )
{
final String message =
REZ.getString( "copy.file-count.notice",
new Integer( count ),
m_destDir.getAbsolutePath() );
getLogger().info( message );
}
}
}

+ 15
- 0
proposal/myrmidon/src/java/org/apache/antlib/file/Resources.properties View File

@@ -19,3 +19,18 @@ delete.delete-file.notice=Deleting {0}.
delete.delete-file.error=Unable to delete file {0}.
delete.delete-file.error=Deleting {0} files from {1}.
delete.summary.notice=Deleted {0,choice,0#zero directories|1#1 directory|2<{0} directories} from {1}.

copy.omit-uptodate.notice={0} omitted as {1} is up to date.
copy.missing-src.error=No source file or fileset specified.
copy.one-dest-only.error=Only one of destFile or destDir may be set.
copy.fileset-for-dirs.error=Use a fileset to copy directories.
copy.need-destdir.error=Cannot copy multiple files into a single file.
copy.bad-mapping.error=Cannot concatenate multiple files into a single file.
copy.bad-operation.error=Cannot perform operation from directory to file.
copy.missing-file.error=Could not find file {0} to copy.
copy.dir-count.notice=Copied {0} empty director{0,choice,1#y|2<ies} to {1}.
copy.file-count.notice=Copying {0} file{0,choice,1#|2<s} to {1}.
copy.dircopy.error=Unable to create directory {0}.
copy.filecopy.error=Failed to copy {0} to {1} due to {3}.
copy.filecopy.notice=Copying {0} to {1}.
copy.selfcopy-ignored.notice=Skipping self-copy of {0}.

Loading…
Cancel
Save