git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271115 13f79535-47bb-0310-9956-ffa450edef68master
@@ -358,6 +358,10 @@ Legal: | |||
<property name="antlib.name" value="core"/> | |||
</ant> | |||
<ant antfile="antlib.xml"> | |||
<property name="antlib.name" value="file"/> | |||
</ant> | |||
<ant antfile="antlib.xml"> | |||
<property name="antlib.name" value="archive"/> | |||
</ant> | |||
@@ -0,0 +1,241 @@ | |||
/* | |||
* 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.util.ArrayList; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
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; | |||
/** | |||
* Deletes a file or directory, or set of files defined by a fileset. | |||
* | |||
* @ant:task name="delete" | |||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> | |||
* @author <a href="mailto:tad1@cornell.edu">Tom Dimock</a> | |||
* @author <a href="mailto:glennm@ca.ibm.com">Glenn McAllister</a> | |||
* @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Delete | |||
extends AbstractTask | |||
{ | |||
private final static Resources REZ = | |||
ResourceManager.getPackageResources( Delete.class ); | |||
private final ArrayList filesets = new ArrayList(); | |||
private File m_dir; | |||
private File m_file; | |||
private boolean m_includeEmpty;// by default, remove matching empty dirs | |||
/** | |||
* Set the directory from which files are to be deleted | |||
* | |||
* @param dir the directory path. | |||
*/ | |||
public void setDir( final File dir ) | |||
{ | |||
m_dir = dir; | |||
} | |||
/** | |||
* Set the name of a single file to be removed. | |||
* | |||
* @param file the file to be deleted | |||
*/ | |||
public void setFile( final File file ) | |||
{ | |||
m_file = file; | |||
} | |||
/** | |||
* Adds a set of files (nested fileset attribute). | |||
*/ | |||
public void addFileset( FileSet set ) | |||
{ | |||
filesets.add( set ); | |||
} | |||
/** | |||
* Delete the file(s). | |||
*/ | |||
public void execute() | |||
throws TaskException | |||
{ | |||
validate(); | |||
// delete the single file | |||
if( null != m_file && m_file.exists() ) | |||
{ | |||
deleteFile( m_file ); | |||
} | |||
// delete the directory | |||
if( m_dir != null && m_dir.exists() && m_dir.isDirectory() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-dir.notice", m_dir.getAbsolutePath() ); | |||
getLogger().info( message ); | |||
deleteDir( m_dir ); | |||
} | |||
// delete the files in the filesets | |||
final int size = filesets.size(); | |||
for( int i = 0; i < size; i++ ) | |||
{ | |||
final FileSet fileSet = (FileSet)filesets.get( i ); | |||
final DirectoryScanner scanner = | |||
ScannerUtil.getDirectoryScanner( fileSet ); | |||
final String[] files = scanner.getIncludedFiles(); | |||
final String[] dirs = scanner.getIncludedDirectories(); | |||
removeFiles( fileSet.getDir(), files, dirs ); | |||
} | |||
} | |||
private void validate() | |||
throws TaskException | |||
{ | |||
if( null == m_file && null == m_dir && 0 == filesets.size() ) | |||
{ | |||
final String message = REZ.getString( "delete.nofiles.error" ); | |||
throw new TaskException( message ); | |||
} | |||
if( null != m_file && m_file.exists() && m_file.isDirectory() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.bad-file.error", m_file.getAbsolutePath() ); | |||
throw new TaskException( message ); | |||
} | |||
if( null != m_file && !m_file.exists() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.missing-file.error", m_file.getAbsolutePath() ); | |||
getLogger().debug( message ); | |||
} | |||
} | |||
private void deleteDir( final File baseDir ) | |||
throws TaskException | |||
{ | |||
final File[] list = baseDir.listFiles(); | |||
if( list != null ) | |||
{ | |||
deleteFiles( list ); | |||
} | |||
if( getLogger().isDebugEnabled() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-dir.notice", m_dir.getAbsolutePath() ); | |||
getLogger().debug( message ); | |||
} | |||
if( !baseDir.delete() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-dir.error", m_dir.getAbsolutePath() ); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
private void deleteFiles( final File[] list ) | |||
throws TaskException | |||
{ | |||
for( int i = 0; i < list.length; i++ ) | |||
{ | |||
final File file = list[ i ]; | |||
if( file.isDirectory() ) | |||
{ | |||
deleteDir( file ); | |||
} | |||
else | |||
{ | |||
deleteFile( file ); | |||
} | |||
} | |||
} | |||
private void deleteFile( final File file ) | |||
throws TaskException | |||
{ | |||
if( getLogger().isDebugEnabled() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-file.notice", file.getAbsolutePath() ); | |||
getLogger().debug( message ); | |||
} | |||
if( !file.delete() ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-file.error", file.getAbsolutePath() ); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
/** | |||
* remove an array of files in a directory, and a list of subdirectories | |||
* which will only be deleted if 'includeEmpty' is true | |||
* | |||
* @param d directory to work from | |||
* @param files array of files to delete; can be of zero length | |||
* @param dirs array of directories to delete; can of zero length | |||
*/ | |||
protected void removeFiles( final File baseDir, | |||
final String[] files, | |||
final String[] dirs ) | |||
throws TaskException | |||
{ | |||
if( files.length > 0 ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.delete-file.error", | |||
new Integer( files.length ), | |||
baseDir.getAbsolutePath() ); | |||
getLogger().info( message ); | |||
for( int i = 0; i < files.length; i++ ) | |||
{ | |||
final File file = new File( baseDir, files[ i ] ); | |||
deleteFile( file ); | |||
} | |||
} | |||
if( dirs.length > 0 && m_includeEmpty ) | |||
{ | |||
int dirCount = 0; | |||
for( int j = dirs.length - 1; j >= 0; j-- ) | |||
{ | |||
final File dir = new File( baseDir, dirs[ j ] ); | |||
final String[] dirFiles = dir.list(); | |||
if( null == dirFiles || 0 == dirFiles.length ) | |||
{ | |||
deleteDir( dir ); | |||
dirCount++; | |||
} | |||
} | |||
if( dirCount > 0 ) | |||
{ | |||
final String message = | |||
REZ.getString( "delete.summary.notice", | |||
new Integer( dirCount ), | |||
baseDir.getAbsolutePath() ); | |||
getLogger().info( message ); | |||
} | |||
} | |||
} | |||
} | |||
@@ -5,20 +5,28 @@ | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.tools.ant.taskdefs.file; | |||
package org.apache.antlib.file; | |||
import java.io.File; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.myrmidon.api.AbstractTask; | |||
import org.apache.myrmidon.api.TaskException; | |||
/** | |||
* Creates a given directory. | |||
* Creates specified directory. | |||
* | |||
* @ant:task name="mkdir" | |||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
* @author duncan@x180.com | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Mkdir | |||
extends AbstractTask | |||
{ | |||
private final static Resources REZ = | |||
ResourceManager.getPackageResources( Mkdir.class ); | |||
private File m_dir; | |||
public void setDir( final File dir ) | |||
@@ -29,16 +37,16 @@ public class Mkdir | |||
public void execute() | |||
throws TaskException | |||
{ | |||
if( m_dir == null ) | |||
if( null == m_dir ) | |||
{ | |||
final String message = "dir attribute is required"; | |||
final String message = REZ.getString( "mkdir.missing-dir.error" ); | |||
throw new TaskException( message ); | |||
} | |||
if( m_dir.isFile() ) | |||
{ | |||
final String message = "Unable to create directory as a file " + | |||
"already exists with that name: " + m_dir.getAbsolutePath(); | |||
final String message = | |||
REZ.getString( "mkdir.file-exists.error", m_dir.getAbsolutePath() ); | |||
throw new TaskException( message ); | |||
} | |||
@@ -47,11 +55,12 @@ public class Mkdir | |||
final boolean result = m_dir.mkdirs(); | |||
if( !result ) | |||
{ | |||
final String message = "Directory " + m_dir.getAbsolutePath() + " creation was not " + | |||
"successful for an unknown reason"; | |||
final String message = | |||
REZ.getString( "mkdir.nocreate.error", m_dir.getAbsolutePath() ); | |||
throw new TaskException( message ); | |||
} | |||
final String message = "Created dir: " + m_dir.getAbsolutePath(); | |||
final String message = | |||
REZ.getString( "mkdir.create.notice", m_dir.getAbsolutePath() ); | |||
getLogger().info( message ); | |||
} | |||
} |
@@ -0,0 +1,21 @@ | |||
mkdir.missing-dir.error=dir attribute is required. | |||
mkdir.file-exists.error=Unable to create directory as a file already exists with that name: "{0}". | |||
mkdir.nocreate.error=Failed to create directory {0} due to an unknown reason. | |||
mkdir.create.notice=Created dir: {0} | |||
touch.neg-time.error=Date of {0} results in negative milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT). | |||
touch.no-files.error=Specify at least one source - a file or a fileset. | |||
touch.use-fileset.error=Use a fileset to touch directories. | |||
touch.readonly-file.error=Can not change modification date of read-only file {0}. | |||
touch.no-touch.error=Could not create file {0} due to {1}. | |||
touch.create.notice=Creating {0}. | |||
delete.nofiles.error=At least one of the file or dir attributes, or a fileset element, must be set. | |||
delete.bad-file.error=Directory {0} cannot be removed using the file attribute. Use dir instead. | |||
delete.missing-file.error=Could not find file {0} to delete. | |||
delete.delete-dir.notice=Deleting directory {0}. | |||
delete.delete-dir.error=Unable to delete directory {0}. | |||
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}. |
@@ -5,7 +5,7 @@ | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.tools.ant.taskdefs.file; | |||
package org.apache.antlib.file; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
@@ -14,6 +14,8 @@ import java.text.DateFormat; | |||
import java.text.ParseException; | |||
import java.util.ArrayList; | |||
import java.util.Locale; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.myrmidon.api.AbstractTask; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.tools.ant.types.DirectoryScanner; | |||
@@ -21,30 +23,34 @@ import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.ScannerUtil; | |||
/** | |||
* Touch a file and/or fileset(s) -- corresponds to the Unix touch command. <p> | |||
* Touch a file and/or fileset(s) -- corresponds to the Unix touch command. | |||
* | |||
* If the file to touch doesn't exist, an empty one is created. </p> <p> | |||
* | |||
* Note: Setting the modification time of files is not supported in JDK 1.1.</p> | |||
* If the file to touch doesn't exist, an empty one is created. </p> | |||
* | |||
* @ant:task name="touch" | |||
* @author <a href="mailto:peter@apache.org">Peter Donald</a> | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author <a href="mailto:mj@servidium.com">Michael J. Sikorsky</a> | |||
* @author <a href="mailto:shaw@servidium.com">Robert Shaw</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class Touch | |||
extends AbstractTask | |||
{ | |||
private final static Resources REZ = | |||
ResourceManager.getPackageResources( Touch.class ); | |||
private long m_millis = -1; | |||
private String m_dateTime; | |||
private String m_datetime; | |||
private ArrayList m_filesets = new ArrayList(); | |||
private File m_file; | |||
/** | |||
* Date in the format MM/DD/YYYY HH:MM AM_PM. | |||
*/ | |||
public void setDatetime( String dateTime ) | |||
public void setDatetime( final String datetime ) | |||
{ | |||
m_dateTime = dateTime; | |||
m_datetime = datetime; | |||
} | |||
/** | |||
@@ -82,7 +88,7 @@ public class Touch | |||
{ | |||
validate(); | |||
if( m_dateTime != null ) | |||
if( m_datetime != null ) | |||
{ | |||
final DateFormat format = | |||
DateFormat.getDateTimeInstance( DateFormat.SHORT, | |||
@@ -90,11 +96,10 @@ public class Touch | |||
Locale.US ); | |||
try | |||
{ | |||
final long millis = format.parse( m_dateTime ).getTime(); | |||
final long millis = format.parse( m_datetime ).getTime(); | |||
if( 0 > millis ) | |||
{ | |||
final String message = "Date of " + m_dateTime + " results in negative " + | |||
"milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT)."; | |||
final String message = REZ.getString( "touch.neg-time.error", m_datetime ); | |||
throw new TaskException( message ); | |||
} | |||
setMillis( millis ); | |||
@@ -113,13 +118,13 @@ public class Touch | |||
{ | |||
if( null == m_file && 0 == m_filesets.size() ) | |||
{ | |||
final String message = "Specify at least one source - a file or a fileset."; | |||
final String message = REZ.getString( "touch.no-files.error" ); | |||
throw new TaskException( message ); | |||
} | |||
if( null != m_file && m_file.exists() && m_file.isDirectory() ) | |||
{ | |||
final String message = "Use a fileset to touch directories."; | |||
final String message = REZ.getString( "touch.use-fileset.error" ); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
@@ -132,11 +137,16 @@ public class Touch | |||
m_millis = System.currentTimeMillis(); | |||
} | |||
if( m_file != null ) | |||
if( null != m_file ) | |||
{ | |||
if( !m_file.exists() ) | |||
{ | |||
getLogger().info( "Creating " + m_file ); | |||
if( getLogger().isInfoEnabled() ) | |||
{ | |||
final String message = REZ.getString( "touch.create.notice", m_file ); | |||
getLogger().info( message ); | |||
} | |||
try | |||
{ | |||
FileOutputStream fos = new FileOutputStream( m_file ); | |||
@@ -145,7 +155,7 @@ public class Touch | |||
} | |||
catch( final IOException ioe ) | |||
{ | |||
final String message = "Could not create " + m_file; | |||
final String message = REZ.getString( "touch.no-touch.error", m_file, ioe ); | |||
throw new TaskException( message, ioe ); | |||
} | |||
} | |||
@@ -157,21 +167,23 @@ public class Touch | |||
final int size = m_filesets.size(); | |||
for( int i = 0; i < size; i++ ) | |||
{ | |||
final FileSet fs = (FileSet)m_filesets.get( i ); | |||
final DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs ); | |||
final File fromDir = fs.getDir(); | |||
final FileSet fileSet = (FileSet)m_filesets.get( i ); | |||
final DirectoryScanner scanner = ScannerUtil.getDirectoryScanner( fileSet ); | |||
final File fromDir = fileSet.getDir(); | |||
final String[] srcFiles = ds.getIncludedFiles(); | |||
final String[] srcDirs = ds.getIncludedDirectories(); | |||
final String[] srcFiles = scanner.getIncludedFiles(); | |||
final String[] srcDirs = scanner.getIncludedDirectories(); | |||
for( int j = 0; j < srcFiles.length; j++ ) | |||
{ | |||
touch( new File( fromDir, srcFiles[ j ] ) ); | |||
final File file = new File( fromDir, srcFiles[ j ] ); | |||
touch( file ); | |||
} | |||
for( int j = 0; j < srcDirs.length; j++ ) | |||
{ | |||
touch( new File( fromDir, srcDirs[ j ] ) ); | |||
final File file = new File( fromDir, srcDirs[ j ] ); | |||
touch( file ); | |||
} | |||
} | |||
} | |||
@@ -181,7 +193,8 @@ public class Touch | |||
{ | |||
if( !file.canWrite() ) | |||
{ | |||
throw new TaskException( "Can not change modification date of read-only file " + file ); | |||
final String message = REZ.getString( "touch.readonly-file.error", file ); | |||
throw new TaskException( message ); | |||
} | |||
final long time = ( m_millis < 0 ) ? System.currentTimeMillis() : m_millis; |
@@ -1,248 +0,0 @@ | |||
/* | |||
* 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.tools.ant.taskdefs.file; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.types.DirectoryScanner; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.ScannerUtil; | |||
/** | |||
* Deletes a file or directory, or set of files defined by a fileset. The | |||
* original delete task would delete a file, or a set of files using the | |||
* include/exclude syntax. The deltree task would delete a directory tree. This | |||
* task combines the functionality of these two originally distinct tasks. <p> | |||
* | |||
* Currently Delete extends MatchingTask. This is intend <i>only</i> to provide | |||
* backwards compatibility for a release. The future position is to use nested | |||
* filesets exclusively.</p> | |||
* | |||
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org"> | |||
* stefano@apache.org</a> | |||
* @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a> | |||
* @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com | |||
* </a> | |||
* @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a> | |||
*/ | |||
public class Delete | |||
extends Task | |||
{ | |||
private final ArrayList filesets = new ArrayList(); | |||
private File m_dir; | |||
private File m_file; | |||
private boolean includeEmpty;// by default, remove matching empty dirs | |||
/** | |||
* Set the directory from which files are to be deleted | |||
* | |||
* @param dir the directory path. | |||
*/ | |||
public void setDir( final File dir ) | |||
{ | |||
m_dir = dir; | |||
} | |||
/** | |||
* Set the name of a single file to be removed. | |||
* | |||
* @param file the file to be deleted | |||
*/ | |||
public void setFile( final File file ) | |||
{ | |||
m_file = file; | |||
} | |||
/** | |||
* Adds a set of files (nested fileset attribute). | |||
* | |||
* @param set The feature to be added to the Fileset attribute | |||
*/ | |||
public void addFileset( FileSet set ) | |||
{ | |||
filesets.add( set ); | |||
} | |||
/** | |||
* Delete the file(s). | |||
* | |||
* @exception TaskException Description of Exception | |||
*/ | |||
public void execute() | |||
throws TaskException | |||
{ | |||
if( m_file == null && m_dir == null && filesets.size() == 0 ) | |||
{ | |||
final String message = "At least one of the file or dir attributes, " + | |||
"or a fileset element, must be set."; | |||
throw new TaskException( message ); | |||
} | |||
// delete the single file | |||
if( null != m_file ) | |||
{ | |||
if( m_file.exists() ) | |||
{ | |||
if( m_file.isDirectory() ) | |||
{ | |||
final String message = "Directory " + m_file.getAbsolutePath() + | |||
" cannot be removed using the file attribute. Use dir instead."; | |||
getLogger().info( message ); | |||
} | |||
else | |||
{ | |||
getLogger().info( "Deleting: " + m_file.getAbsolutePath() ); | |||
if( !m_file.delete() ) | |||
{ | |||
final String message = "Unable to delete file " + m_file.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
final String message = | |||
"Could not find file " + m_file.getAbsolutePath() + " to delete."; | |||
getLogger().debug( message ); | |||
} | |||
} | |||
// delete the directory | |||
if( m_dir != null && m_dir.exists() && m_dir.isDirectory() ) | |||
{ | |||
getLogger().info( "Deleting directory " + m_dir.getAbsolutePath() ); | |||
removeDir( m_dir ); | |||
} | |||
// delete the files in the filesets | |||
final int size = filesets.size(); | |||
for( int i = 0; i < size; i++ ) | |||
{ | |||
final FileSet fileSet = (FileSet)filesets.get( i ); | |||
try | |||
{ | |||
final DirectoryScanner scanner = | |||
ScannerUtil.getDirectoryScanner( fileSet ); | |||
String[] files = scanner.getIncludedFiles(); | |||
String[] dirs = scanner.getIncludedDirectories(); | |||
removeFiles( fileSet.getDir(), files, dirs ); | |||
} | |||
catch( TaskException be ) | |||
{ | |||
// directory doesn't exist or is not readable | |||
throw be; | |||
} | |||
} | |||
} | |||
//************************************************************************ | |||
// protected and private methods | |||
//************************************************************************ | |||
protected void removeDir( final File baseDir ) | |||
throws TaskException | |||
{ | |||
final File[] list = baseDir.listFiles(); | |||
if( list != null ) | |||
{ | |||
deleteFiles( list ); | |||
} | |||
getLogger().debug( "Deleting directory " + baseDir.getAbsolutePath() ); | |||
if( !baseDir.delete() ) | |||
{ | |||
String message = "Unable to delete directory " + m_dir.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
private void deleteFiles( final File[] list ) | |||
throws TaskException | |||
{ | |||
for( int i = 0; i < list.length; i++ ) | |||
{ | |||
final File file = list[ i ]; | |||
if( file.isDirectory() ) | |||
{ | |||
removeDir( file ); | |||
} | |||
else | |||
{ | |||
getLogger().debug( "Deleting " + file.getAbsolutePath() ); | |||
if( !file.delete() ) | |||
{ | |||
String message = "Unable to delete file " + file.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* remove an array of files in a directory, and a list of subdirectories | |||
* which will only be deleted if 'includeEmpty' is true | |||
* | |||
* @param d directory to work from | |||
* @param files array of files to delete; can be of zero length | |||
* @param dirs array of directories to delete; can of zero length | |||
*/ | |||
protected void removeFiles( final File baseDir, | |||
final String[] files, | |||
final String[] dirs ) | |||
throws TaskException | |||
{ | |||
if( files.length > 0 ) | |||
{ | |||
final String message = "Deleting " + files.length + " files from " + baseDir.getAbsolutePath(); | |||
getLogger().info( message ); | |||
for( int i = 0; i < files.length; i++ ) | |||
{ | |||
final File file = new File( baseDir, files[ i ] ); | |||
getLogger().debug( "Deleting " + file.getAbsolutePath() ); | |||
if( !file.delete() ) | |||
{ | |||
String message2 = "Unable to delete file " + file.getAbsolutePath(); | |||
throw new TaskException( message2 ); | |||
} | |||
} | |||
} | |||
if( dirs.length > 0 && includeEmpty ) | |||
{ | |||
int dirCount = 0; | |||
for( int j = dirs.length - 1; j >= 0; j-- ) | |||
{ | |||
File dir = new File( baseDir, dirs[ j ] ); | |||
String[] dirFiles = dir.list(); | |||
if( dirFiles == null || dirFiles.length == 0 ) | |||
{ | |||
getLogger().debug( "Deleting " + dir.getAbsolutePath() ); | |||
if( !dir.delete() ) | |||
{ | |||
final String message = | |||
"Unable to delete directory " + dir.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
else | |||
{ | |||
dirCount++; | |||
} | |||
} | |||
} | |||
if( dirCount > 0 ) | |||
{ | |||
final String message = "Deleted " + dirCount + " director" + | |||
( dirCount == 1 ? "y" : "ies" ) + " from " + baseDir.getAbsolutePath(); | |||
getLogger().info( message ); | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,58 +0,0 @@ | |||
/* | |||
* 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.tools.ant.taskdefs.file; | |||
import java.io.File; | |||
import org.apache.myrmidon.api.AbstractTask; | |||
import org.apache.myrmidon.api.TaskException; | |||
/** | |||
* Creates a given directory. | |||
* | |||
* @author duncan@x180.com | |||
*/ | |||
public class Mkdir | |||
extends AbstractTask | |||
{ | |||
private File m_dir; | |||
public void setDir( final File dir ) | |||
{ | |||
m_dir = dir; | |||
} | |||
public void execute() | |||
throws TaskException | |||
{ | |||
if( m_dir == null ) | |||
{ | |||
final String message = "dir attribute is required"; | |||
throw new TaskException( message ); | |||
} | |||
if( m_dir.isFile() ) | |||
{ | |||
final String message = "Unable to create directory as a file " + | |||
"already exists with that name: " + m_dir.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
if( !m_dir.exists() ) | |||
{ | |||
final boolean result = m_dir.mkdirs(); | |||
if( !result ) | |||
{ | |||
final String message = "Directory " + m_dir.getAbsolutePath() + " creation was not " + | |||
"successful for an unknown reason"; | |||
throw new TaskException( message ); | |||
} | |||
final String message = "Created dir: " + m_dir.getAbsolutePath(); | |||
getLogger().info( message ); | |||
} | |||
} | |||
} |
@@ -1,190 +0,0 @@ | |||
/* | |||
* 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.tools.ant.taskdefs.file; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.text.DateFormat; | |||
import java.text.ParseException; | |||
import java.util.ArrayList; | |||
import java.util.Locale; | |||
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; | |||
/** | |||
* Touch a file and/or fileset(s) -- corresponds to the Unix touch command. <p> | |||
* | |||
* If the file to touch doesn't exist, an empty one is created. </p> <p> | |||
* | |||
* Note: Setting the modification time of files is not supported in JDK 1.1.</p> | |||
* | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author <a href="mailto:mj@servidium.com">Michael J. Sikorsky</a> | |||
* @author <a href="mailto:shaw@servidium.com">Robert Shaw</a> | |||
*/ | |||
public class Touch | |||
extends AbstractTask | |||
{ | |||
private long m_millis = -1; | |||
private String m_dateTime; | |||
private ArrayList m_filesets = new ArrayList(); | |||
private File m_file; | |||
/** | |||
* Date in the format MM/DD/YYYY HH:MM AM_PM. | |||
*/ | |||
public void setDatetime( String dateTime ) | |||
{ | |||
m_dateTime = dateTime; | |||
} | |||
/** | |||
* Sets a single source file to touch. If the file does not exist an empty | |||
* file will be created. | |||
*/ | |||
public void setFile( final File file ) | |||
{ | |||
m_file = file; | |||
} | |||
/** | |||
* Milliseconds since 01/01/1970 00:00 am. | |||
*/ | |||
public void setMillis( final long millis ) | |||
{ | |||
m_millis = millis; | |||
} | |||
/** | |||
* Adds a set of files (nested fileset attribute). | |||
*/ | |||
public void addFileset( final FileSet set ) | |||
{ | |||
m_filesets.add( set ); | |||
} | |||
/** | |||
* Execute the touch operation. | |||
* | |||
* @exception TaskException Description of Exception | |||
*/ | |||
public void execute() | |||
throws TaskException | |||
{ | |||
validate(); | |||
if( m_dateTime != null ) | |||
{ | |||
final DateFormat format = | |||
DateFormat.getDateTimeInstance( DateFormat.SHORT, | |||
DateFormat.SHORT, | |||
Locale.US ); | |||
try | |||
{ | |||
final long millis = format.parse( m_dateTime ).getTime(); | |||
if( 0 > millis ) | |||
{ | |||
final String message = "Date of " + m_dateTime + " results in negative " + | |||
"milliseconds value relative to epoch (January 1, 1970, 00:00:00 GMT)."; | |||
throw new TaskException( message ); | |||
} | |||
setMillis( millis ); | |||
} | |||
catch( final ParseException pe ) | |||
{ | |||
throw new TaskException( pe.getMessage(), pe ); | |||
} | |||
} | |||
touch(); | |||
} | |||
private void validate() | |||
throws TaskException | |||
{ | |||
if( null == m_file && 0 == m_filesets.size() ) | |||
{ | |||
final String message = "Specify at least one source - a file or a fileset."; | |||
throw new TaskException( message ); | |||
} | |||
if( null != m_file && m_file.exists() && m_file.isDirectory() ) | |||
{ | |||
final String message = "Use a fileset to touch directories."; | |||
throw new TaskException( message ); | |||
} | |||
} | |||
private void touch() | |||
throws TaskException | |||
{ | |||
if( m_millis < 0 ) | |||
{ | |||
m_millis = System.currentTimeMillis(); | |||
} | |||
if( m_file != null ) | |||
{ | |||
if( !m_file.exists() ) | |||
{ | |||
getLogger().info( "Creating " + m_file ); | |||
try | |||
{ | |||
FileOutputStream fos = new FileOutputStream( m_file ); | |||
fos.write( new byte[ 0 ] ); | |||
fos.close(); | |||
} | |||
catch( final IOException ioe ) | |||
{ | |||
final String message = "Could not create " + m_file; | |||
throw new TaskException( message, ioe ); | |||
} | |||
} | |||
touch( m_file ); | |||
} | |||
// deal with the filesets | |||
final int size = m_filesets.size(); | |||
for( int i = 0; i < size; i++ ) | |||
{ | |||
final FileSet fs = (FileSet)m_filesets.get( i ); | |||
final DirectoryScanner ds = ScannerUtil.getDirectoryScanner( fs ); | |||
final File fromDir = fs.getDir(); | |||
final String[] srcFiles = ds.getIncludedFiles(); | |||
final String[] srcDirs = ds.getIncludedDirectories(); | |||
for( int j = 0; j < srcFiles.length; j++ ) | |||
{ | |||
touch( new File( fromDir, srcFiles[ j ] ) ); | |||
} | |||
for( int j = 0; j < srcDirs.length; j++ ) | |||
{ | |||
touch( new File( fromDir, srcDirs[ j ] ) ); | |||
} | |||
} | |||
} | |||
private void touch( final File file ) | |||
throws TaskException | |||
{ | |||
if( !file.canWrite() ) | |||
{ | |||
throw new TaskException( "Can not change modification date of read-only file " + file ); | |||
} | |||
final long time = ( m_millis < 0 ) ? System.currentTimeMillis() : m_millis; | |||
file.setLastModified( time ); | |||
} | |||
} |
@@ -20,7 +20,7 @@ import org.apache.tools.ant.taskdefs.Java; | |||
import org.apache.tools.ant.taskdefs.Javac; | |||
import org.apache.tools.ant.taskdefs.MatchingTask; | |||
import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; | |||
import org.apache.tools.ant.taskdefs.file.Mkdir; | |||
import org.apache.antlib.file.Mkdir; | |||
import org.apache.tools.ant.types.DirectoryScanner; | |||
import org.apache.tools.ant.types.Path; | |||
@@ -195,4 +195,10 @@ Legal: | |||
<log message="Ungzipped file!"/> | |||
</target> | |||
<target name="file-test"> | |||
<mkdir dir="/tmp/deleteme"/> | |||
<touch file="/tmp/deleteme/touch-test"/> | |||
<delete dir="/tmp/deleteme"/> | |||
</target> | |||
</project> |
@@ -1,248 +0,0 @@ | |||
/* | |||
* 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.tools.ant.taskdefs.file; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.types.DirectoryScanner; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.ScannerUtil; | |||
/** | |||
* Deletes a file or directory, or set of files defined by a fileset. The | |||
* original delete task would delete a file, or a set of files using the | |||
* include/exclude syntax. The deltree task would delete a directory tree. This | |||
* task combines the functionality of these two originally distinct tasks. <p> | |||
* | |||
* Currently Delete extends MatchingTask. This is intend <i>only</i> to provide | |||
* backwards compatibility for a release. The future position is to use nested | |||
* filesets exclusively.</p> | |||
* | |||
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org"> | |||
* stefano@apache.org</a> | |||
* @author Tom Dimock <a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a> | |||
* @author Glenn McAllister <a href="mailto:glennm@ca.ibm.com">glennm@ca.ibm.com | |||
* </a> | |||
* @author Jon S. Stevens <a href="mailto:jon@latchkey.com">jon@latchkey.com</a> | |||
*/ | |||
public class Delete | |||
extends Task | |||
{ | |||
private final ArrayList filesets = new ArrayList(); | |||
private File m_dir; | |||
private File m_file; | |||
private boolean includeEmpty;// by default, remove matching empty dirs | |||
/** | |||
* Set the directory from which files are to be deleted | |||
* | |||
* @param dir the directory path. | |||
*/ | |||
public void setDir( final File dir ) | |||
{ | |||
m_dir = dir; | |||
} | |||
/** | |||
* Set the name of a single file to be removed. | |||
* | |||
* @param file the file to be deleted | |||
*/ | |||
public void setFile( final File file ) | |||
{ | |||
m_file = file; | |||
} | |||
/** | |||
* Adds a set of files (nested fileset attribute). | |||
* | |||
* @param set The feature to be added to the Fileset attribute | |||
*/ | |||
public void addFileset( FileSet set ) | |||
{ | |||
filesets.add( set ); | |||
} | |||
/** | |||
* Delete the file(s). | |||
* | |||
* @exception TaskException Description of Exception | |||
*/ | |||
public void execute() | |||
throws TaskException | |||
{ | |||
if( m_file == null && m_dir == null && filesets.size() == 0 ) | |||
{ | |||
final String message = "At least one of the file or dir attributes, " + | |||
"or a fileset element, must be set."; | |||
throw new TaskException( message ); | |||
} | |||
// delete the single file | |||
if( null != m_file ) | |||
{ | |||
if( m_file.exists() ) | |||
{ | |||
if( m_file.isDirectory() ) | |||
{ | |||
final String message = "Directory " + m_file.getAbsolutePath() + | |||
" cannot be removed using the file attribute. Use dir instead."; | |||
getLogger().info( message ); | |||
} | |||
else | |||
{ | |||
getLogger().info( "Deleting: " + m_file.getAbsolutePath() ); | |||
if( !m_file.delete() ) | |||
{ | |||
final String message = "Unable to delete file " + m_file.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
final String message = | |||
"Could not find file " + m_file.getAbsolutePath() + " to delete."; | |||
getLogger().debug( message ); | |||
} | |||
} | |||
// delete the directory | |||
if( m_dir != null && m_dir.exists() && m_dir.isDirectory() ) | |||
{ | |||
getLogger().info( "Deleting directory " + m_dir.getAbsolutePath() ); | |||
removeDir( m_dir ); | |||
} | |||
// delete the files in the filesets | |||
final int size = filesets.size(); | |||
for( int i = 0; i < size; i++ ) | |||
{ | |||
final FileSet fileSet = (FileSet)filesets.get( i ); | |||
try | |||
{ | |||
final DirectoryScanner scanner = | |||
ScannerUtil.getDirectoryScanner( fileSet ); | |||
String[] files = scanner.getIncludedFiles(); | |||
String[] dirs = scanner.getIncludedDirectories(); | |||
removeFiles( fileSet.getDir(), files, dirs ); | |||
} | |||
catch( TaskException be ) | |||
{ | |||
// directory doesn't exist or is not readable | |||
throw be; | |||
} | |||
} | |||
} | |||
//************************************************************************ | |||
// protected and private methods | |||
//************************************************************************ | |||
protected void removeDir( final File baseDir ) | |||
throws TaskException | |||
{ | |||
final File[] list = baseDir.listFiles(); | |||
if( list != null ) | |||
{ | |||
deleteFiles( list ); | |||
} | |||
getLogger().debug( "Deleting directory " + baseDir.getAbsolutePath() ); | |||
if( !baseDir.delete() ) | |||
{ | |||
String message = "Unable to delete directory " + m_dir.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
private void deleteFiles( final File[] list ) | |||
throws TaskException | |||
{ | |||
for( int i = 0; i < list.length; i++ ) | |||
{ | |||
final File file = list[ i ]; | |||
if( file.isDirectory() ) | |||
{ | |||
removeDir( file ); | |||
} | |||
else | |||
{ | |||
getLogger().debug( "Deleting " + file.getAbsolutePath() ); | |||
if( !file.delete() ) | |||
{ | |||
String message = "Unable to delete file " + file.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
} | |||
} | |||
} | |||
/** | |||
* remove an array of files in a directory, and a list of subdirectories | |||
* which will only be deleted if 'includeEmpty' is true | |||
* | |||
* @param d directory to work from | |||
* @param files array of files to delete; can be of zero length | |||
* @param dirs array of directories to delete; can of zero length | |||
*/ | |||
protected void removeFiles( final File baseDir, | |||
final String[] files, | |||
final String[] dirs ) | |||
throws TaskException | |||
{ | |||
if( files.length > 0 ) | |||
{ | |||
final String message = "Deleting " + files.length + " files from " + baseDir.getAbsolutePath(); | |||
getLogger().info( message ); | |||
for( int i = 0; i < files.length; i++ ) | |||
{ | |||
final File file = new File( baseDir, files[ i ] ); | |||
getLogger().debug( "Deleting " + file.getAbsolutePath() ); | |||
if( !file.delete() ) | |||
{ | |||
String message2 = "Unable to delete file " + file.getAbsolutePath(); | |||
throw new TaskException( message2 ); | |||
} | |||
} | |||
} | |||
if( dirs.length > 0 && includeEmpty ) | |||
{ | |||
int dirCount = 0; | |||
for( int j = dirs.length - 1; j >= 0; j-- ) | |||
{ | |||
File dir = new File( baseDir, dirs[ j ] ); | |||
String[] dirFiles = dir.list(); | |||
if( dirFiles == null || dirFiles.length == 0 ) | |||
{ | |||
getLogger().debug( "Deleting " + dir.getAbsolutePath() ); | |||
if( !dir.delete() ) | |||
{ | |||
final String message = | |||
"Unable to delete directory " + dir.getAbsolutePath(); | |||
throw new TaskException( message ); | |||
} | |||
else | |||
{ | |||
dirCount++; | |||
} | |||
} | |||
} | |||
if( dirCount > 0 ) | |||
{ | |||
final String message = "Deleted " + dirCount + " director" + | |||
( dirCount == 1 ? "y" : "ies" ) + " from " + baseDir.getAbsolutePath(); | |||
getLogger().info( message ); | |||
} | |||
} | |||
} | |||
} | |||
@@ -20,7 +20,7 @@ import org.apache.tools.ant.taskdefs.Java; | |||
import org.apache.tools.ant.taskdefs.Javac; | |||
import org.apache.tools.ant.taskdefs.MatchingTask; | |||
import org.apache.tools.ant.taskdefs.compilers.DefaultCompilerAdapter; | |||
import org.apache.tools.ant.taskdefs.file.Mkdir; | |||
import org.apache.antlib.file.Mkdir; | |||
import org.apache.tools.ant.types.DirectoryScanner; | |||
import org.apache.tools.ant.types.Path; | |||