You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by do...@apache.org on 2001/12/30 10:58:25 UTC
cvs commit: jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text FixCRLF.java NestedString.java Replace.java Replacefilter.java
donaldp 01/12/30 01:58:25
Modified: proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs
Filter.java
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide
VAJWorkspaceScanner.java
proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/net
FTP.java
Added: proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text
FixCRLF.java NestedString.java Replace.java
Replacefilter.java
Removed: proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs
FixCRLF.java NestedString.java Replace.java
Replacefilter.java
Log:
Move text manipulation tasks into new package
Revision Changes Path
1.7 +2 -1 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Filter.java
Index: Filter.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Filter.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Filter.java 23 Dec 2001 14:21:50 -0000 1.6
+++ Filter.java 30 Dec 2001 09:58:25 -0000 1.7
@@ -21,7 +21,8 @@
* @author Gero Vermaas <a href="mailto:gero@xs4all.nl">gero@xs4all.nl</a>
* @author <A href="gholam@xtra.co.nz">Michael McCallum</A>
*/
-public class Filter extends Task
+public class Filter
+ extends Task
{
private File filtersFile;
1.6 +10 -10 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
Index: VAJWorkspaceScanner.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- VAJWorkspaceScanner.java 23 Dec 2001 06:31:57 -0000 1.5
+++ VAJWorkspaceScanner.java 30 Dec 2001 09:58:25 -0000 1.6
@@ -94,12 +94,12 @@
*/
public void addDefaultExcludes()
{
- int excludesLength = excludes == null ? 0 : excludes.length;
+ int excludesLength = getExcludes() == null ? 0 : getExcludes().length;
String[] newExcludes;
newExcludes = new String[ excludesLength + DEFAULTEXCLUDES.length ];
if( excludesLength > 0 )
{
- System.arraycopy( excludes, 0, newExcludes, 0, excludesLength );
+ System.arraycopy( getExcludes(), 0, newExcludes, 0, excludesLength );
}
for( int i = 0; i < DEFAULTEXCLUDES.length; i++ )
{
@@ -107,7 +107,7 @@
replace( '/', File.separatorChar ).
replace( '\\', File.separatorChar );
}
- excludes = newExcludes;
+ setExcludes( newExcludes );
}
/**
@@ -125,10 +125,10 @@
for( int i = 0; i < projects.length; i++ )
{
Project project = projects[ i ];
- for( int j = 0; j < includes.length && !allProjectsMatch; j++ )
+ for( int j = 0; j < getIncludes().length && !allProjectsMatch; j++ )
{
StringTokenizer tok =
- new StringTokenizer( includes[ j ], File.separator );
+ new StringTokenizer( getIncludes()[ j ], File.separator );
String projectNamePattern = tok.nextToken();
if( projectNamePattern.equals( "**" ) )
{
@@ -162,15 +162,15 @@
*/
public void scan()
{
- if( includes == null )
+ if( getIncludes() == null )
{
// No includes supplied, so set it to 'matches all'
- includes = new String[ 1 ];
- includes[ 0 ] = "**";
+ setIncludes( new String[ 1 ] );
+ getIncludes()[ 0 ] = "**";
}
- if( excludes == null )
+ if( getExcludes() == null )
{
- excludes = new String[ 0 ];
+ setExcludes( new String[ 0 ] );
}
// only scan projects which are included in at least one include pattern
1.10 +17 -17 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
Index: FTP.java
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- FTP.java 23 Dec 2001 14:22:47 -0000 1.9
+++ FTP.java 30 Dec 2001 09:58:25 -0000 1.10
@@ -962,23 +962,23 @@
public void scan()
{
- if( includes == null )
+ if( getIncludes() == null )
{
// No includes supplied, so set it to 'matches all'
- includes = new String[ 1 ];
- includes[ 0 ] = "**";
+ setIncludes( new String[ 1 ] );
+ getIncludes()[ 0 ] = "**";
}
- if( excludes == null )
+ if( getExcludes() == null )
{
- excludes = new String[ 0 ];
+ setExcludes( new String[ 0 ] );
}
- filesIncluded = new ArrayList();
- filesNotIncluded = new ArrayList();
- filesExcluded = new ArrayList();
- dirsIncluded = new ArrayList();
- dirsNotIncluded = new ArrayList();
- dirsExcluded = new ArrayList();
+ setFilesIncluded( new ArrayList() );
+ setFilesNotIncluded( new ArrayList() );
+ setFilesExcluded( new ArrayList() );
+ setDirsIncluded( new ArrayList() );
+ setDirsNotIncluded( new ArrayList() );
+ setDirsExcluded( new ArrayList() );
try
{
@@ -1020,7 +1020,7 @@
{
if( !isExcluded( name ) )
{
- dirsIncluded.add( name );
+ getDirsIncluded().add( name );
if( fast )
{
scandir( name, vpath + name + File.separator, fast );
@@ -1028,12 +1028,12 @@
}
else
{
- dirsExcluded.add( name );
+ getDirsExcluded().add( name );
}
}
else
{
- dirsNotIncluded.add( name );
+ getDirsNotIncluded().add( name );
if( fast && couldHoldIncluded( name ) )
{
scandir( name, vpath + name + File.separator, fast );
@@ -1053,16 +1053,16 @@
{
if( !isExcluded( name ) )
{
- filesIncluded.add( name );
+ getFilesIncluded().add( name );
}
else
{
- filesExcluded.add( name );
+ getFilesExcluded().add( name );
}
}
else
{
- filesNotIncluded.add( name );
+ getFilesNotIncluded().add( name );
}
}
}
1.1 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text/FixCRLF.java
Index: FixCRLF.java
===================================================================
/*
* 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.text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.EnumeratedAttribute;
import org.apache.tools.ant.util.FileUtils;
/**
* Task to convert text source files to local OS formatting conventions, as well
* as repair text files damaged by misconfigured or misguided editors or file
* transfer programs. <p>
*
* This task can take the following arguments:
* <ul>
* <li> srcdir
* <li> destdir
* <li> include
* <li> exclude
* <li> cr
* <li> eol
* <li> tab
* <li> eof
* <li> encoding
* </ul>
* Of these arguments, only <b>sourcedir</b> is required. <p>
*
* When this task executes, it will scan the srcdir based on the include and
* exclude properties. <p>
*
* This version generalises the handling of EOL characters, and allows for
* CR-only line endings (which I suspect is the standard on Macs.) Tab handling
* has also been generalised to accommodate any tabwidth from 2 to 80,
* inclusive. Importantly, it will leave untouched any literal TAB characters
* embedded within string or character constants. <p>
*
* <em>Warning:</em> do not run on binary files. <em>Caution:</em> run with care
* on carefully formatted files. This may sound obvious, but if you don't
* specify asis, presume that your files are going to be modified. If "tabs" is
* "add" or "remove", whitespace characters may be added or removed as
* necessary. Similarly, for CR's - in fact "eol"="crlf" or cr="add" can result
* in cr characters being removed in one special case accommodated, i.e., CRCRLF
* is regarded as a single EOL to handle cases where other programs have
* converted CRLF into CRCRLF.
*
* @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a>
* @author <a href="mailto:pbwest@powerup.com.au">Peter B. West</a>
* @version $Revision: 1.1 $ $Name: $
*/
public class FixCRLF
extends MatchingTask
{
private final static int UNDEF = -1;
private final static int NOTJAVA = 0;
private final static int LOOKING = 1;
private final static int IN_CHAR_CONST = 2;
private final static int IN_STR_CONST = 3;
private final static int IN_SINGLE_COMMENT = 4;
private final static int IN_MULTI_COMMENT = 5;
private final static int ASIS = 0;
private final static int CR = 1;
private final static int LF = 2;
private final static int CRLF = 3;
private final static int ADD = 1;
private final static int REMOVE = -1;
private final static int SPACES = -1;
private final static int TABS = 1;
private final static int INBUFLEN = 8192;
private final static int LINEBUFLEN = 200;
private final static char CTRLZ = '\u001A';
private int tablength = 8;
private String spaces = " ";
private StringBuffer linebuf = new StringBuffer( 1024 );
private StringBuffer linebuf2 = new StringBuffer( 1024 );
private boolean javafiles = false;
private File destDir = null;
/**
* Encoding to assume for the files
*/
private String encoding = null;
private int ctrlz;
private int eol;
private String eolstr;
private File srcDir;
private int tabs;
/**
* Defaults the properties based on the system type.
* <ul>
* <li> Unix: eol="LF" tab="asis" eof="remove"
* <li> Mac: eol="CR" tab="asis" eof="remove"
* <li> DOS: eol="CRLF" tab="asis" eof="asis"
* </ul>
*
*/
public FixCRLF()
{
tabs = ASIS;
if( File.pathSeparator.equals( ":" ) )
{
ctrlz = REMOVE;
if( System.getProperty( "os.name" ).indexOf( "Mac" ) > -1 )
{
eol = CR;
eolstr = "\r";
}
else
{
eol = LF;
eolstr = "\n";
}
}
else
{
ctrlz = ASIS;
eol = CRLF;
eolstr = "\r\n";
}
}
/**
* Set the destination where the fixed files should be placed. Default is to
* replace the original file.
*
* @param destDir The new Destdir value
*/
public void setDestdir( File destDir )
{
this.destDir = destDir;
}
/**
* Specifies the encoding Ant expects the files to be in - defaults to the
* platforms default encoding.
*
* @param encoding The new Encoding value
*/
public void setEncoding( String encoding )
{
this.encoding = encoding;
}
/**
* Specify how DOS EOF (control-z) charaters are to be handled
*
* @param attr The new Eof value
*/
public void setEof( AddAsisRemove attr )
{
String option = attr.getValue();
if( option.equals( "remove" ) )
{
ctrlz = REMOVE;
}
else if( option.equals( "asis" ) )
{
ctrlz = ASIS;
}
else
{
// must be "add"
ctrlz = ADD;
}
}
/**
* Specify how EndOfLine characters are to be handled
*
* @param attr The new Eol value
*/
public void setEol( CrLf attr )
{
String option = attr.getValue();
if( option.equals( "asis" ) )
{
eol = ASIS;
}
else if( option.equals( "cr" ) )
{
eol = CR;
eolstr = "\r";
}
else if( option.equals( "lf" ) )
{
eol = LF;
eolstr = "\n";
}
else
{
// Must be "crlf"
eol = CRLF;
eolstr = "\r\n";
}
}
/**
* Fixing Java source files?
*
* @param javafiles The new Javafiles value
*/
public void setJavafiles( boolean javafiles )
{
this.javafiles = javafiles;
}
/**
* Set the source dir to find the source text files.
*
* @param srcDir The new Srcdir value
*/
public void setSrcdir( File srcDir )
{
this.srcDir = srcDir;
}
/**
* Specify how tab characters are to be handled
*
* @param attr The new Tab value
*/
public void setTab( AddAsisRemove attr )
{
String option = attr.getValue();
if( option.equals( "remove" ) )
{
tabs = SPACES;
}
else if( option.equals( "asis" ) )
{
tabs = ASIS;
}
else
{
// must be "add"
tabs = TABS;
}
}
/**
* Specify tab length in characters
*
* @param tlength specify the length of tab in spaces,
* @exception TaskException Description of Exception
*/
public void setTablength( int tlength )
throws TaskException
{
if( tlength < 2 || tlength > 80 )
{
throw new TaskException( "tablength must be between 2 and 80" );
}
tablength = tlength;
StringBuffer sp = new StringBuffer();
for( int i = 0; i < tablength; i++ )
{
sp.append( ' ' );
}
spaces = sp.toString();
}
/**
* Executes the task.
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{
// first off, make sure that we've got a srcdir and destdir
if( srcDir == null )
{
throw new TaskException( "srcdir attribute must be set!" );
}
if( !srcDir.exists() )
{
throw new TaskException( "srcdir does not exist!" );
}
if( !srcDir.isDirectory() )
{
throw new TaskException( "srcdir is not a directory!" );
}
if( destDir != null )
{
if( !destDir.exists() )
{
throw new TaskException( "destdir does not exist!" );
}
if( !destDir.isDirectory() )
{
throw new TaskException( "destdir is not a directory!" );
}
}
// log options used
getLogger().debug( "options:" +
" eol=" +
( eol == ASIS ? "asis" : eol == CR ? "cr" : eol == LF ? "lf" : "crlf" ) +
" tab=" + ( tabs == TABS ? "add" : tabs == ASIS ? "asis" : "remove" ) +
" eof=" + ( ctrlz == ADD ? "add" : ctrlz == ASIS ? "asis" : "remove" ) +
" tablength=" + tablength +
" encoding=" + ( encoding == null ? "default" : encoding ) );
DirectoryScanner ds = super.getDirectoryScanner( srcDir );
String[] files = ds.getIncludedFiles();
for( int i = 0; i < files.length; i++ )
{
processFile( files[ i ] );
}
}
/**
* Creates a Reader reading from a given file an taking the user defined
* encoding into account.
*
* @param f Description of Parameter
* @return The Reader value
* @exception IOException Description of Exception
*/
private Reader getReader( File f )
throws IOException
{
return ( encoding == null ) ? new FileReader( f )
: new InputStreamReader( new FileInputStream( f ), encoding );
}
/**
* Scan a BufferLine forward from the 'next' pointer for the end of a
* character constant. Set 'lookahead' pointer to the character following
* the terminating quote.
*
* @param bufline Description of Parameter
* @param terminator Description of Parameter
* @exception TaskException Description of Exception
*/
private void endOfCharConst( OneLiner.BufferLine bufline, char terminator )
throws TaskException
{
int ptr = bufline.getNext();
int eol = bufline.length();
char c;
ptr++;// skip past initial quote
while( ptr < eol )
{
if( ( c = bufline.getChar( ptr++ ) ) == '\\' )
{
ptr++;
}
else
{
if( c == terminator )
{
bufline.setLookahead( ptr );
return;
}
}
}// end of while (ptr < eol)
// Must have fallen through to the end of the line
throw new TaskException( "endOfCharConst: unterminated char constant" );
}
/**
* Scan a BufferLine for the next state changing token: the beginning of a
* single or multi-line comment, a character or a string constant. As a
* side-effect, sets the buffer state to the next state, and sets field
* lookahead to the first character of the state-changing token, or to the
* next eol character.
*
* @param bufline Description of Parameter
* @exception TaskException Description of Exception
*/
private void nextStateChange( OneLiner.BufferLine bufline )
throws TaskException
{
int eol = bufline.length();
int ptr = bufline.getNext();
// Look for next single or double quote, double slash or slash star
while( ptr < eol )
{
switch( bufline.getChar( ptr++ ) )
{
case '\'':
bufline.setState( IN_CHAR_CONST );
bufline.setLookahead( --ptr );
return;
case '\"':
bufline.setState( IN_STR_CONST );
bufline.setLookahead( --ptr );
return;
case '/':
if( ptr < eol )
{
if( bufline.getChar( ptr ) == '*' )
{
bufline.setState( IN_MULTI_COMMENT );
bufline.setLookahead( --ptr );
return;
}
else if( bufline.getChar( ptr ) == '/' )
{
bufline.setState( IN_SINGLE_COMMENT );
bufline.setLookahead( --ptr );
return;
}
}
break;
}// end of switch (bufline.getChar(ptr++))
}// end of while (ptr < eol)
// Eol is the next token
bufline.setLookahead( ptr );
}
/**
* Process a BufferLine string which is not part of of a string constant.
* The start position of the string is given by the 'next' field. Sets the
* 'next' and 'column' fields in the BufferLine.
*
* @param bufline Description of Parameter
* @param end Description of Parameter
* @param outWriter Description of Parameter
*/
private void notInConstant( OneLiner.BufferLine bufline, int end,
BufferedWriter outWriter )
throws TaskException
{
// N.B. both column and string index are zero-based
// Process a string not part of a constant;
// i.e. convert tabs<->spaces as required
// This is NOT called for ASIS tab handling
int nextTab;
int nextStop;
int tabspaces;
String line = bufline.substring( bufline.getNext(), end );
int place = 0;// Zero-based
int col = bufline.getColumn();// Zero-based
// process sequences of white space
// first convert all tabs to spaces
linebuf.setLength( 0 );
while( ( nextTab = line.indexOf( (int)'\t', place ) ) >= 0 )
{
linebuf.append( line.substring( place, nextTab ) );// copy to the TAB
col += nextTab - place;
tabspaces = tablength - ( col % tablength );
linebuf.append( spaces.substring( 0, tabspaces ) );
col += tabspaces;
place = nextTab + 1;
}// end of while
linebuf.append( line.substring( place, line.length() ) );
// if converting to spaces, all finished
String linestring = new String( linebuf.toString() );
if( tabs == REMOVE )
{
try
{
outWriter.write( linestring );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}// end of try-catch
}
else
{// tabs == ADD
int tabCol;
linebuf2.setLength( 0 );
place = 0;
col = bufline.getColumn();
int placediff = col - 0;
// for the length of the string, cycle through the tab stop
// positions, checking for a space preceded by at least one
// other space at the tab stop. if so replace the longest possible
// preceding sequence of spaces with a tab.
nextStop = col + ( tablength - col % tablength );
if( nextStop - col < 2 )
{
linebuf2.append( linestring.substring(
place, nextStop - placediff ) );
place = nextStop - placediff;
nextStop += tablength;
}
for( ; nextStop - placediff <= linestring.length()
; nextStop += tablength )
{
for( tabCol = nextStop;
--tabCol - placediff >= place
&& linestring.charAt( tabCol - placediff ) == ' '
; )
{
;// Loop for the side-effects
}
// tabCol is column index of the last non-space character
// before the next tab stop
if( nextStop - tabCol > 2 )
{
linebuf2.append( linestring.substring(
place, ++tabCol - placediff ) );
linebuf2.append( '\t' );
}
else
{
linebuf2.append( linestring.substring(
place, nextStop - placediff ) );
}// end of else
place = nextStop - placediff;
}// end of for (nextStop ... )
// pick up that last bit, if any
linebuf2.append( linestring.substring( place, linestring.length() ) );
try
{
outWriter.write( linebuf2.toString() );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}// end of try-catch
}// end of else tabs == ADD
// Set column position as modified by this method
bufline.setColumn( bufline.getColumn() + linestring.length() );
bufline.setNext( end );
}
private void processFile( String file )
throws TaskException
{
File srcFile = new File( srcDir, file );
File destD = destDir == null ? srcDir : destDir;
File tmpFile = null;
BufferedWriter outWriter;
OneLiner.BufferLine line;
// read the contents of the file
OneLiner lines = new OneLiner( srcFile );
try
{
// Set up the output Writer
try
{
tmpFile = File.createTempFile( "fixcrlf", "", destD );
Writer writer = ( encoding == null ) ? new FileWriter( tmpFile )
: new OutputStreamWriter( new FileOutputStream( tmpFile ), encoding );
outWriter = new BufferedWriter( writer );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
while( lines.hasNext() )
{
// In-line states
int endComment;
try
{
line = (OneLiner.BufferLine)lines.next();
}
catch( NoSuchElementException e )
{
throw new TaskException( "Error", e );
}
String lineString = line.getLineString();
int linelen = line.length();
// Note - all of the following processing NOT done for
// tabs ASIS
if( tabs == ASIS )
{
// Just copy the body of the line across
try
{
outWriter.write( lineString );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}// end of try-catch
}
else
{// (tabs != ASIS)
int ptr;
while( ( ptr = line.getNext() ) < linelen )
{
switch( lines.getState() )
{
case NOTJAVA:
notInConstant( line, line.length(), outWriter );
break;
case IN_MULTI_COMMENT:
if( ( endComment =
lineString.indexOf( "*/", line.getNext() )
) >= 0 )
{
// End of multiLineComment on this line
endComment += 2;// Include the end token
lines.setState( LOOKING );
}
else
{
endComment = linelen;
}
notInConstant( line, endComment, outWriter );
break;
case IN_SINGLE_COMMENT:
notInConstant( line, line.length(), outWriter );
lines.setState( LOOKING );
break;
case IN_CHAR_CONST:
case IN_STR_CONST:
// Got here from LOOKING by finding an opening "\'"
// next points to that quote character.
// Find the end of the constant. Watch out for
// backslashes. Literal tabs are left unchanged, and
// the column is adjusted accordingly.
int begin = line.getNext();
char terminator = ( lines.getState() == IN_STR_CONST
? '\"'
: '\'' );
endOfCharConst( line, terminator );
while( line.getNext() < line.getLookahead() )
{
if( line.getNextCharInc() == '\t' )
{
line.setColumn(
line.getColumn() +
tablength -
line.getColumn() % tablength );
}
else
{
line.incColumn();
}
}
// Now output the substring
try
{
outWriter.write( line.substring( begin, line.getNext() ) );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
lines.setState( LOOKING );
break;
case LOOKING:
nextStateChange( line );
notInConstant( line, line.getLookahead(), outWriter );
break;
}// end of switch (state)
}// end of while (line.getNext() < linelen)
}// end of else (tabs != ASIS)
try
{
outWriter.write( eolstr );
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}// end of try-catch
}// end of while (lines.hasNext())
try
{
// Handle CTRLZ
if( ctrlz == ASIS )
{
outWriter.write( lines.getEofStr() );
}
else if( ctrlz == ADD )
{
outWriter.write( CTRLZ );
}
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
finally
{
try
{
outWriter.close();
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
}
File destFile = new File( destD, file );
try
{
lines.close();
lines = null;
}
catch( IOException e )
{
throw new TaskException( "Unable to close source file " + srcFile );
}
if( destFile.exists() )
{
// Compare the destination with the temp file
getLogger().debug( "destFile exists" );
if( !contentEquals( destFile, tmpFile ) )
{
getLogger().debug( destFile + " is being written" );
if( !destFile.delete() )
{
throw new TaskException( "Unable to delete "
+ destFile );
}
if( !tmpFile.renameTo( destFile ) )
{
throw new TaskException(
"Failed to transform " + srcFile
+ " to " + destFile
+ ". Couldn't rename temporary file: "
+ tmpFile );
}
}
else
{// destination is equal to temp file
getLogger().debug( destFile + " is not written, as the contents are identical" );
if( !tmpFile.delete() )
{
throw new TaskException( "Unable to delete "
+ tmpFile );
}
}
}
else
{// destFile does not exist - write the temp file
///XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
getLogger().debug( "destFile does not exist" );
if( !tmpFile.renameTo( destFile ) )
{
throw new TaskException(
"Failed to transform " + srcFile
+ " to " + destFile
+ ". Couldn't rename temporary file: "
+ tmpFile );
}
}
tmpFile = null;
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
finally
{
try
{
if( lines != null )
{
lines.close();
}
}
catch( IOException io )
{
getLogger().error( "Error closing " + srcFile );
}// end of catch
if( tmpFile != null )
{
tmpFile.delete();
}
}// end of finally
}
private boolean contentEquals( File f1, File f2 )
throws IOException
{
if( f1.exists() != f2.exists() )
{
return false;
}
if( !f1.exists() )
{
// two not existing files are equal
return true;
}
if( f1.isDirectory() || f2.isDirectory() )
{
// don't want to compare directory contents for now
return false;
}
InputStream in1 = null;
InputStream in2 = null;
try
{
in1 = new BufferedInputStream( new FileInputStream( f1 ) );
in2 = new BufferedInputStream( new FileInputStream( f2 ) );
int expectedByte = in1.read();
while( expectedByte != -1 )
{
if( expectedByte != in2.read() )
{
return false;
}
expectedByte = in1.read();
}
if( in2.read() != -1 )
{
return false;
}
return true;
}
finally
{
if( in1 != null )
{
try
{
in1.close();
}
catch( IOException e )
{
}
}
if( in2 != null )
{
try
{
in2.close();
}
catch( IOException e )
{
}
}
}
}
/**
* Enumerated attribute with the values "asis", "add" and "remove".
*
* @author RT
*/
public static class AddAsisRemove extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"add", "asis", "remove"};
}
}
/**
* Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
*
* @author RT
*/
public static class CrLf extends EnumeratedAttribute
{
public String[] getValues()
{
return new String[]{"asis", "cr", "lf", "crlf"};
}
}
class OneLiner
implements Iterator
{
private int state = javafiles ? LOOKING : NOTJAVA;
private StringBuffer eolStr = new StringBuffer( LINEBUFLEN );
private StringBuffer eofStr = new StringBuffer();
private StringBuffer line = new StringBuffer();
private boolean reachedEof = false;
private BufferedReader reader;
public OneLiner( File srcFile )
throws TaskException
{
try
{
reader = new BufferedReader
( getReader( srcFile ), INBUFLEN );
nextLine();
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
}
public void remove()
{
throw new UnsupportedOperationException();
}
public void setState( int state )
{
this.state = state;
}
public String getEofStr()
{
return eofStr.toString();
}
public int getState()
{
return state;
}
public void close()
throws IOException
{
if( reader != null )
{
reader.close();
}
}
public boolean hasNext()
{
return !reachedEof;
}
public Object next()
throws NoSuchElementException
{
if( !hasNext() )
{
throw new NoSuchElementException( "OneLiner" );
}
try
{
BufferLine tmpLine =
new BufferLine( line.toString(), eolStr.toString() );
nextLine();
return tmpLine;
}
catch( TaskException e )
{
throw new NoSuchElementException();
}
}
protected void nextLine()
throws TaskException
{
int ch = -1;
int eolcount = 0;
eolStr.setLength( 0 );
line.setLength( 0 );
try
{
ch = reader.read();
while( ch != -1 && ch != '\r' && ch != '\n' )
{
line.append( (char)ch );
ch = reader.read();
}
if( ch == -1 && line.length() == 0 )
{
// Eof has been reached
reachedEof = true;
return;
}
switch( (char)ch )
{
case '\r':
// Check for \r, \r\n and \r\r\n
// Regard \r\r not followed by \n as two lines
++eolcount;
eolStr.append( '\r' );
switch( (char)( ch = reader.read() ) )
{
case '\r':
if( (char)( ch = reader.read() ) == '\n' )
{
eolcount += 2;
eolStr.append( "\r\n" );
}
break;
case '\n':
++eolcount;
eolStr.append( '\n' );
break;
}// end of switch ((char)(ch = reader.read()))
break;
case '\n':
++eolcount;
eolStr.append( '\n' );
break;
}// end of switch ((char) ch)
// if at eolcount == 0 and trailing characters of string
// are CTRL-Zs, set eofStr
if( eolcount == 0 )
{
int i = line.length();
while( --i >= 0 && line.charAt( i ) == CTRLZ )
{
// keep searching for the first ^Z
}
if( i < line.length() - 1 )
{
// Trailing characters are ^Zs
// Construct new line and eofStr
eofStr.append( line.toString().substring( i + 1 ) );
if( i < 0 )
{
line.setLength( 0 );
reachedEof = true;
}
else
{
line.setLength( i + 1 );
}
}
}// end of if (eolcount == 0)
}
catch( IOException e )
{
throw new TaskException( "Error", e );
}
}
class BufferLine
{
private int next = 0;
private int column = 0;
private int lookahead = UNDEF;
private String eolStr;
private String line;
public BufferLine( String line, String eolStr )
throws TaskException
{
next = 0;
column = 0;
this.line = line;
this.eolStr = eolStr;
}
public void setColumn( int col )
{
column = col;
}
public void setLookahead( int lookahead )
{
this.lookahead = lookahead;
}
public void setNext( int next )
{
this.next = next;
}
public void setState( int state )
{
OneLiner.this.setState( state );
}
public char getChar( int i )
{
return line.charAt( i );
}
public int getColumn()
{
return column;
}
public String getEol()
{
return eolStr;
}
public int getEolLength()
{
return eolStr.length();
}
public String getLineString()
{
return line;
}
public int getLookahead()
{
return lookahead;
}
public int getNext()
{
return next;
}
public char getNextChar()
{
return getChar( next );
}
public char getNextCharInc()
{
return getChar( next++ );
}
public int getState()
{
return OneLiner.this.getState();
}
public int incColumn()
{
return column++;
}
public int length()
{
return line.length();
}
public String substring( int begin )
{
return line.substring( begin );
}
public String substring( int begin, int end )
{
return line.substring( begin, end );
}
}
}
}
1.1 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text/NestedString.java
Index: NestedString.java
===================================================================
/*
* 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.text;
public class NestedString
{
private String m_text = "";
public String getText()
{
return m_text;
}
public void addContent( final String text )
{
m_text = text;
}
}
1.1 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text/Replace.java
Index: Replace.java
===================================================================
/*
* 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.text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Properties;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.avalon.excalibur.util.StringUtil;
/**
* Replaces all occurrences of one or more string tokens with given values in
* the indicated files. Each value can be either a string or the value of a
* property available in a designated property file.
*
* @author Stefano Mazzocchi <a href="mailto:stefano@apache.org">
* stefano@apache.org</a>
* @author <a href="mailto:erik@desknetinc.com">Erik Langenbach</a>
*/
public class Replace
extends MatchingTask
{
private File m_src;
private NestedString m_token;
private NestedString m_value = new NestedString();
private File m_propertyFile;
private Properties m_properties;
private ArrayList m_replacefilters = new ArrayList();
private File m_dir;
private boolean m_summary;
/**
* The encoding used to read and write files - if null, uses default
*/
private String m_encoding;
private int m_fileCount;
private int m_replaceCount;
/**
* Set the source files path when using matching tasks.
*
* @param dir The new Dir value
*/
public void setDir( File dir )
{
m_dir = dir;
}
/**
* Set the file encoding to use on the files read and written by replace
*
* @param encoding the encoding to use on the files
*/
public void setEncoding( String encoding )
{
m_encoding = encoding;
}
/**
* Set the source file.
*
* @param file The new File value
*/
public void setFile( File file )
{
m_src = file;
}
/**
* Sets a file to be searched for property values.
*
* @param filename The new PropertyFile value
*/
public void setPropertyFile( File filename )
{
m_propertyFile = filename;
}
/**
* Request a summary
*
* @param summary true if you would like a summary logged of the replace
* operation
*/
public void setSummary( boolean summary )
{
m_summary = summary;
}
/**
* Set the string token to replace.
*
* @param token The new Token value
*/
public void setToken( String token )
{
createReplaceToken().addContent( token );
}
/**
* Set the string value to use as token replacement.
*
* @param value The new Value value
*/
public void setValue( String value )
{
createReplaceValue().addContent( value );
}
public Properties getProperties( File propertyFile )
throws TaskException
{
Properties properties = new Properties();
try
{
properties.load( new FileInputStream( propertyFile ) );
}
catch( FileNotFoundException e )
{
String message = "Property file (" + propertyFile.getPath() + ") not found.";
throw new TaskException( message );
}
catch( IOException e )
{
String message = "Property file (" + propertyFile.getPath() + ") cannot be loaded.";
throw new TaskException( message );
}
return properties;
}
/**
* Nested <replacetoken> element.
*
* @return Description of the Returned Value
*/
public NestedString createReplaceToken()
{
if( m_token == null )
{
m_token = new NestedString();
}
return m_token;
}
/**
* Nested <replacevalue> element.
*
* @return Description of the Returned Value
*/
public NestedString createReplaceValue()
{
return m_value;
}
/**
* Add nested <replacefilter> element.
*
* @return Description of the Returned Value
*/
public Replacefilter createReplacefilter()
{
Replacefilter filter = new Replacefilter( this );
m_replacefilters.add( filter );
return filter;
}
/**
* Do the execution.
*
* @exception TaskException Description of Exception
*/
public void execute()
throws TaskException
{
validateAttributes();
if( m_propertyFile != null )
{
m_properties = getProperties( m_propertyFile );
}
validateReplacefilters();
m_fileCount = 0;
m_replaceCount = 0;
if( m_src != null )
{
processFile( m_src );
}
if( m_dir != null )
{
DirectoryScanner ds = super.getDirectoryScanner( m_dir );
String[] srcs = ds.getIncludedFiles();
for( int i = 0; i < srcs.length; i++ )
{
File file = new File( m_dir, srcs[ i ] );
processFile( file );
}
}
if( m_summary )
{
getLogger().info( "Replaced " + m_replaceCount + " occurrences in " + m_fileCount + " files." );
}
}
/**
* Validate attributes provided for this task in .xml build file.
*
* @exception TaskException if any supplied attribute is invalid or any
* mandatory attribute is missing
*/
public void validateAttributes()
throws TaskException
{
if( m_src == null && m_dir == null )
{
String message = "Either the file or the dir attribute " + "must be specified";
throw new TaskException( message );
}
if( m_propertyFile != null && !m_propertyFile.exists() )
{
String message = "Property file " + m_propertyFile.getPath() + " does not exist.";
throw new TaskException( message );
}
if( m_token == null && m_replacefilters.size() == 0 )
{
String message = "Either token or a nested replacefilter "
+ "must be specified";
throw new TaskException( message );
}
if( m_token != null && "".equals( m_token.getText() ) )
{
String message = "The token attribute must not be an empty string.";
throw new TaskException( message );
}
}
/**
* Validate nested elements.
*
* @exception TaskException if any supplied attribute is invalid or any
* mandatory attribute is missing
*/
public void validateReplacefilters()
throws TaskException
{
for( int i = 0; i < m_replacefilters.size(); i++ )
{
Replacefilter element = (Replacefilter)m_replacefilters.get( i );
element.validate();
}
}
/**
* Perform the replacement on the given file. The replacement is performed
* on a temporary file which then replaces the original file.
*
* @param src the source file
* @exception TaskException Description of Exception
*/
private void processFile( File src )
throws TaskException
{
if( !src.exists() )
{
throw new TaskException( "Replace: source file " + src.getPath() + " doesn't exist" );
}
File temp = null;
try
{
temp = File.createTempFile( "rep", ".tmp", src.getParentFile() );
}
catch( IOException ioe )
{
throw new TaskException( ioe.toString(), ioe );
}
Reader reader = null;
Writer writer = null;
try
{
reader = m_encoding == null ? new FileReader( src )
: new InputStreamReader( new FileInputStream( src ), m_encoding );
writer = m_encoding == null ? new FileWriter( temp )
: new OutputStreamWriter( new FileOutputStream( temp ), m_encoding );
BufferedReader br = new BufferedReader( reader );
BufferedWriter bw = new BufferedWriter( writer );
// read the entire file into a StringBuffer
// size of work buffer may be bigger than needed
// when multibyte characters exist in the source file
// but then again, it might be smaller than needed on
// platforms like Windows where length can't be trusted
int fileLengthInBytes = (int)( src.length() );
StringBuffer tmpBuf = new StringBuffer( fileLengthInBytes );
int readChar = 0;
int totread = 0;
while( true )
{
readChar = br.read();
if( readChar < 0 )
{
break;
}
tmpBuf.append( (char)readChar );
totread++;
}
// create a String so we can use indexOf
String buf = tmpBuf.toString();
//Preserve original string (buf) so we can compare the result
String newString = new String( buf );
if( m_token != null )
{
// line separators in values and tokens are "\n"
// in order to compare with the file contents, replace them
// as needed
final String val = stringReplace( m_value.getText(), "\n", StringUtil.LINE_SEPARATOR );
final String tok = stringReplace( m_token.getText(), "\n", StringUtil.LINE_SEPARATOR );
// for each found token, replace with value
getLogger().debug( "Replacing in " + src.getPath() + ": " + m_token.getText() + " --> " + m_value.getText() );
newString = stringReplace( newString, tok, val );
}
if( m_replacefilters.size() > 0 )
{
newString = processReplacefilters( newString, src.getPath() );
}
boolean changes = !newString.equals( buf );
if( changes )
{
bw.write( newString, 0, newString.length() );
bw.flush();
}
// cleanup
bw.close();
writer = null;
br.close();
reader = null;
// If there were changes, move the new one to the old one;
// otherwise, delete the new one
if( changes )
{
++m_fileCount;
src.delete();
temp.renameTo( src );
temp = null;
}
}
catch( IOException ioe )
{
throw new TaskException( "IOException in " + src + " - " +
ioe.getClass().getName() + ":" + ioe.getMessage(), ioe );
}
finally
{
if( reader != null )
{
try
{
reader.close();
}
catch( IOException e )
{
}
}
if( writer != null )
{
try
{
writer.close();
}
catch( IOException e )
{
}
}
if( temp != null )
{
temp.delete();
}
}
}
private String processReplacefilters( String buffer, String filename )
{
String newString = new String( buffer );
for( int i = 0; i < m_replacefilters.size(); i++ )
{
Replacefilter filter = (Replacefilter)m_replacefilters.get( i );
//for each found token, replace with value
getLogger().debug( "Replacing in " + filename + ": " + filter.getToken() + " --> " + filter.getReplaceValue() );
newString = stringReplace( newString, filter.getToken(), filter.getReplaceValue() );
}
return newString;
}
/**
* Replace occurrences of str1 in string str with str2
*
* @param str Description of Parameter
* @param str1 Description of Parameter
* @param str2 Description of Parameter
* @return Description of the Returned Value
*/
private String stringReplace( String str, String str1, String str2 )
{
StringBuffer ret = new StringBuffer();
int start = 0;
int found = str.indexOf( str1 );
while( found >= 0 )
{
// write everything up to the found str1
if( found > start )
{
ret.append( str.substring( start, found ) );
}
// write the replacement str2
if( str2 != null )
{
ret.append( str2 );
}
// search again
start = found + str1.length();
found = str.indexOf( str1, start );
++m_replaceCount;
}
// write the remaining characters
if( str.length() > start )
{
ret.append( str.substring( start, str.length() ) );
}
return ret.toString();
}
public NestedString getValue()
{
return m_value;
}
public File getPropertyFile()
{
return m_propertyFile;
}
public Properties getProperties()
{
return m_properties;
}
}
1.1 jakarta-ant/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/text/Replacefilter.java
Index: Replacefilter.java
===================================================================
/*
* 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.text;
import org.apache.myrmidon.api.TaskException;
public class Replacefilter
{
private String m_property;
private String m_token;
private String m_value;
private Replace m_replace;
public Replacefilter( Replace replace )
{
m_replace = replace;
}
public void setProperty( final String property )
{
this.m_property = property;
}
public void setToken( String token )
{
this.m_token = token;
}
public void setValue( String value )
{
this.m_value = value;
}
public String getProperty()
{
return m_property;
}
public String getReplaceValue()
{
if( m_property != null )
{
return (String)m_replace.getProperties().getProperty( m_property );
}
else if( m_value != null )
{
return m_value;
}
else if( m_replace.getValue() != null )
{
return m_replace.getValue().getText();
}
else
{
//Default is empty string
return "";
}
}
public String getToken()
{
return m_token;
}
public String getValue()
{
return m_value;
}
public void validate()
throws TaskException
{
//Validate mandatory attributes
if( m_token == null )
{
String message = "token is a mandatory attribute " + "of replacefilter.";
throw new TaskException( message );
}
if( "".equals( m_token ) )
{
String message = "The token attribute must not be an empty string.";
throw new TaskException( message );
}
//value and property are mutually exclusive attributes
if( ( m_value != null ) && ( m_property != null ) )
{
String message = "Either value or property " + "can be specified, but a replacefilter " + "element cannot have both.";
throw new TaskException( message );
}
if( ( m_property != null ) )
{
//the property attribute must have access to a property file
if( m_replace.getPropertyFile() == null )
{
String message = "The replacefilter's property attribute " +
"can only be used with the replacetask's propertyFile attribute.";
throw new TaskException( message );
}
//Make sure property exists in property file
if( m_replace.getProperties() == null ||
m_replace.getProperties().getProperty( m_property ) == null )
{
String message = "property \"" + m_property + "\" was not found in " + m_replace.getPropertyFile().getPath();
throw new TaskException( message );
}
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>