FileDocCategorySizeDatePackage
Replace.javaAPI DocApache Ant 1.7027729Wed Dec 13 06:16:24 GMT 2006org.apache.tools.ant.taskdefs

Replace

public class Replace extends MatchingTask
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. If you want to replace a text that crosses line boundaries, you must use a nested <replacetoken> element.
since
Ant 1.1
ant.task
category="filesystem"

Fields Summary
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
private File
src
private NestedString
token
private NestedString
value
private File
propertyFile
private File
replaceFilterFile
private Properties
properties
private Vector
replacefilters
private File
dir
private int
fileCount
private int
replaceCount
private boolean
summary
private String
encoding
The encoding used to read and write files - if null, uses default
Constructors Summary
Methods Summary
private java.lang.StringBufferbuildFilterChain(java.lang.StringBuffer inputBuffer)
Creates the chain of filters to operate.

param
inputBuffer StringBuffer containing the input for the first filter.
return
StringBuffer containing the output of the last filter.

        StringBuffer buf = inputBuffer;
        for (int i = 0; i < replacefilters.size(); i++) {
            Replacefilter filter = (Replacefilter) replacefilters.elementAt(i);
            filter.setInputBuffer(buf);
            buf = filter.getOutputBuffer();
        }
        return buf;
    
private org.apache.tools.ant.taskdefs.Replace$ReplacefiltercreatePrimaryfilter()
Adds the token and value as first <replacefilter> element. The token and value are always processed first.

return
a nested Replacefilter object to be configured.

        Replacefilter filter = new Replacefilter();
        replacefilters.insertElementAt(filter, 0);
        return filter;
    
public org.apache.tools.ant.taskdefs.Replace$NestedStringcreateReplaceToken()
Create a token to filter as the text of a nested element.

return
nested token NestedString to configure.

        if (token == null) {
            token = new NestedString();
        }
        return token;
    
public org.apache.tools.ant.taskdefs.Replace$NestedStringcreateReplaceValue()
Create a string to replace the token as the text of a nested element.

return
replacement value NestedString to configure.

        return value;
    
public org.apache.tools.ant.taskdefs.Replace$ReplacefiltercreateReplacefilter()
Add a nested <replacefilter> element.

return
a nested Replacefilter object to be configured.

        Replacefilter filter = new Replacefilter();
        replacefilters.addElement(filter);
        return filter;
    
public voidexecute()
Do the execution.

throws
BuildException if we cant build


        Vector savedFilters = (Vector) replacefilters.clone();
        Properties savedProperties =
            properties == null ? null : (Properties) properties.clone();

        if (token != null) {
            // line separators in values and tokens are "\n"
            // in order to compare with the file contents, replace them
            // as needed
            StringBuffer val = new StringBuffer(value.getText());
            stringReplace(val, "\r\n", "\n");
            stringReplace(val, "\n", StringUtils.LINE_SEP);
            StringBuffer tok = new StringBuffer(token.getText());
            stringReplace(tok, "\r\n", "\n");
            stringReplace(tok, "\n", StringUtils.LINE_SEP);
            Replacefilter firstFilter = createPrimaryfilter();
            firstFilter.setToken(tok.toString());
            firstFilter.setValue(val.toString());
        }

        try {
            if (replaceFilterFile != null) {
                Properties props = getProperties(replaceFilterFile);
                Enumeration e = props.keys();
                while (e.hasMoreElements()) {
                    String tok =  e.nextElement().toString();
                    Replacefilter replaceFilter = createReplacefilter();
                    replaceFilter.setToken(tok);
                    replaceFilter.setValue(props.getProperty(tok));
                }
            }

            validateAttributes();

            if (propertyFile != null) {
                properties = getProperties(propertyFile);
            }

            validateReplacefilters();
            fileCount = 0;
            replaceCount = 0;

            if (src != null) {
                processFile(src);
            }

            if (dir != null) {
                DirectoryScanner ds = super.getDirectoryScanner(dir);
                String[] srcs = ds.getIncludedFiles();

                for (int i = 0; i < srcs.length; i++) {
                    File file = new File(dir, srcs[i]);
                    processFile(file);
                }
            }

            if (summary) {
                log("Replaced " + replaceCount + " occurrences in "
                    + fileCount + " files.", Project.MSG_INFO);
            }
        } finally {
            replacefilters = savedFilters;
            properties = savedProperties;
        } // end of finally

    
private voidflushFilterChain()
Flushes all filters.

        for (int i = 0; i < replacefilters.size(); i++) {
            Replacefilter filter = (Replacefilter) replacefilters.elementAt(i);
            filter.flush();
        }
    
public java.util.PropertiesgetProperties(java.io.File propertyFile)
Load a properties file.

param
propertyFile the file to load the properties from.
return
loaded Properties object.
throws
BuildException if the file could not be found or read.

        Properties props = new Properties();

        FileInputStream in = null;
        try {
            in = new FileInputStream(propertyFile);
            props.load(in);
        } catch (FileNotFoundException e) {
            String message = "Property file (" + propertyFile.getPath()
                + ") not found.";
            throw new BuildException(message);
        } catch (IOException e) {
            String message = "Property file (" + propertyFile.getPath()
                + ") cannot be loaded.";
            throw new BuildException(message);
        } finally {
            FileUtils.close(in);
        }

        return props;
    
private voidlogFilterChain(java.lang.String filename)
Logs the chain of filters to operate on the file.

param
filename String.

        for (int i = 0; i < replacefilters.size(); i++) {
            Replacefilter filter = (Replacefilter) replacefilters.elementAt(i);
            log("Replacing in " + filename + ": " + filter.getToken()
                    + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE);
        }
    
private voidprocessFile(java.io.File src)
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.

        if (!src.exists()) {
            throw new BuildException("Replace: source file " + src.getPath()
                                     + " doesn't exist", getLocation());
        }

        File temp = null;
        FileInput in = null;
        FileOutput out = null;
        try {
            in = new FileInput(src);

            temp = FILE_UTILS.createTempFile("rep", ".tmp",
                    src.getParentFile());
            out = new FileOutput(temp);

            int repCountStart = replaceCount;

            logFilterChain(src.getPath());

            out.setInputBuffer(buildFilterChain(in.getOutputBuffer()));

            while (in.readChunk()) {
                if (processFilterChain()) {
                    out.process();
                }
            }

            flushFilterChain();

            out.flush();
            in.close();
            in = null;
            out.close();
            out = null;

            boolean changes = (replaceCount != repCountStart);
            if (changes) {
                FILE_UTILS.rename(temp, src);
                temp = null;
            }
        } catch (IOException ioe) {
            throw new BuildException("IOException in " + src + " - "
                    + ioe.getClass().getName() + ":"
                    + ioe.getMessage(), ioe, getLocation());
        } finally {
            if (null != in) {
                in.closeQuietly();
            }
            if (null != out) {
                out.closeQuietly();
            }
            if (temp != null) {
                if (!temp.delete()) {
                    temp.deleteOnExit();
                }
            }
        }
    
private booleanprocessFilterChain()
Performs the normal processing of the filters.

return
true if the filter chain produced new output.

        for (int i = 0; i < replacefilters.size(); i++) {
            Replacefilter filter = (Replacefilter) replacefilters.elementAt(i);
            if (!filter.process()) {
                return false;
            }
        }
        return true;
    
public voidsetDir(java.io.File dir)
The base directory to use when replacing a token in multiple files; required if file is not defined.

param
dir File representing the base directory.

        this.dir = dir;
    
public voidsetEncoding(java.lang.String encoding)
Set the file encoding to use on the files read and written by the task; optional, defaults to default JVM encoding.

param
encoding the encoding to use on the files.

        this.encoding = encoding;
    
public voidsetFile(java.io.File file)
Set the source file; required unless dir is set.

param
file source File.

        this.src = file;
    
public voidsetPropertyFile(java.io.File propertyFile)
The name of a property file from which properties specified using nested <replacefilter> elements are drawn; required only if the property attribute of <replacefilter> is used.

param
propertyFile File to load.

        this.propertyFile = propertyFile;
    
public voidsetReplaceFilterFile(java.io.File replaceFilterFile)
Sets the name of a property file containing filters; optional. Each property will be treated as a replacefilter where token is the name of the property and value is the value of the property.

param
replaceFilterFile File to load.

        this.replaceFilterFile = replaceFilterFile;
    
public voidsetSummary(boolean summary)
Indicates whether a summary of the replace operation should be produced, detailing how many token occurrences and files were processed; optional, default=false.

param
summary boolean whether a summary of the replace operation should be logged.

        this.summary = summary;
    
public voidsetToken(java.lang.String token)
Set the string token to replace; required unless a nested replacetoken element or the replacefilterfile attribute is used.

param
token token String.

        createReplaceToken().addText(token);
    
public voidsetValue(java.lang.String value)
Set the string value to use as token replacement; optional, default is the empty string "".

param
value replacement value.

        createReplaceValue().addText(value);
    
private voidstringReplace(java.lang.StringBuffer str, java.lang.String str1, java.lang.String str2)
Replace occurrences of str1 in StringBuffer str with str2.

        int found = str.toString().indexOf(str1);
        while (found >= 0) {
            str.replace(found, found + str1.length(), str2);
            found = str.toString().indexOf(str1, found + str2.length());
        }
    
public voidvalidateAttributes()
Validate attributes provided for this task in .xml build file.

exception
BuildException if any supplied attribute is invalid or any mandatory attribute is missing.

        if (src == null && dir == null) {
            String message = "Either the file or the dir attribute "
                + "must be specified";
            throw new BuildException(message, getLocation());
        }
        if (propertyFile != null && !propertyFile.exists()) {
            String message = "Property file " + propertyFile.getPath()
                + " does not exist.";
            throw new BuildException(message, getLocation());
        }
        if (token == null && replacefilters.size() == 0) {
            String message = "Either token or a nested replacefilter "
                + "must be specified";
            throw new BuildException(message, getLocation());
        }
        if (token != null && "".equals(token.getText())) {
            String message = "The token attribute must not be an empty string.";
            throw new BuildException(message, getLocation());
        }
    
public voidvalidateReplacefilters()
Validate nested elements.

exception
BuildException if any supplied attribute is invalid or any mandatory attribute is missing.

        for (int i = 0; i < replacefilters.size(); i++) {
            Replacefilter element =
                (Replacefilter) replacefilters.elementAt(i);
            element.validate();
        }