Browse Source

add Appendable interface with echo as first supporting task

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@713173 13f79535-47bb-0310-9956-ffa450edef68
master
Matthew Jason Benson 16 years ago
parent
commit
3ae69e82c3
7 changed files with 240 additions and 49 deletions
  1. +13
    -25
      src/main/org/apache/tools/ant/taskdefs/Echo.java
  2. +35
    -0
      src/main/org/apache/tools/ant/types/resources/Appendable.java
  3. +18
    -4
      src/main/org/apache/tools/ant/types/resources/FileResource.java
  4. +68
    -0
      src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
  5. +42
    -5
      src/main/org/apache/tools/ant/util/FileUtils.java
  6. +61
    -15
      src/main/org/apache/tools/ant/util/ResourceUtils.java
  7. +3
    -0
      src/tests/antunit/taskdefs/echo-test.xml

+ 13
- 25
src/main/org/apache/tools/ant/taskdefs/Echo.java View File

@@ -20,20 +20,18 @@ package org.apache.tools.ant.taskdefs;


import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;


import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task; import org.apache.tools.ant.Task;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.ResourceUtils;
import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.types.LogLevel; import org.apache.tools.ant.types.LogLevel;
import org.apache.tools.ant.types.Resource; import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource; import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.LogOutputResource;
import org.apache.tools.ant.types.resources.StringResource;


/** /**
* Writes a message to the Ant logging facilities. * Writes a message to the Ant logging facilities.
@@ -62,23 +60,14 @@ public class Echo extends Task {
* @exception BuildException if something goes wrong with the build * @exception BuildException if something goes wrong with the build
*/ */
public void execute() throws BuildException { public void execute() throws BuildException {
if (output == null) {
log(message, logLevel);
} else {
Writer out = null;
try {
OutputStream os = output instanceof FileProvider ? os = new FileOutputStream(
((FileProvider) output).getFile(), append) : output.getOutputStream();
OutputStreamWriter osw = (encoding == null || "".equals(encoding)) ? new OutputStreamWriter(
os)
: new OutputStreamWriter(os, encoding);
out = new BufferedWriter(osw);
out.write(message, 0, message.length());
} catch (IOException ioe) {
throw new BuildException(ioe, getLocation());
} finally {
FileUtils.close(out);
}
final String msg = "".equals(message) ? StringUtils.LINE_SEP : message;
try {
ResourceUtils
.copyResource(new StringResource(msg), output == null ? new LogOutputResource(
this, logLevel) : output, null, null, false, false, append, null, ""
.equals(encoding) ? null : encoding, getProject());
} catch (IOException ioe) {
throw new BuildException(ioe, getLocation());
} }
} }


@@ -88,7 +77,7 @@ public class Echo extends Task {
* @param msg Sets the value for the message variable. * @param msg Sets the value for the message variable.
*/ */
public void setMessage(String msg) { public void setMessage(String msg) {
this.message = msg;
this.message = msg == null ? "" : msg;
} }


/** /**
@@ -97,7 +86,6 @@ public class Echo extends Task {
* standard output * standard output
*/ */
public void setFile(File file) { public void setFile(File file) {
this.file = file;
setOutput(new FileResource(getProject(), file)); setOutput(new FileResource(getProject(), file));
} }




+ 35
- 0
src/main/org/apache/tools/ant/types/resources/Appendable.java View File

@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.IOException;
import java.io.OutputStream;

/**
* Interface to be implemented by "appendable" resources.
* @since Ant 1.8
*/
public interface Appendable {

/**
* Get an appending OutputStream.
* @return OutputStream
* @throws IOException if anything goes wrong
*/
OutputStream getAppendOutputStream() throws IOException;
}

+ 18
- 4
src/main/org/apache/tools/ant/types/resources/FileResource.java View File

@@ -36,7 +36,7 @@ import org.apache.tools.ant.types.ResourceFactory;
* @since Ant 1.7 * @since Ant 1.7
*/ */
public class FileResource extends Resource implements Touchable, FileProvider, public class FileResource extends Resource implements Touchable, FileProvider,
ResourceFactory {
ResourceFactory, Appendable {


private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
private static final int NULL_FILE private static final int NULL_FILE
@@ -209,11 +209,25 @@ public class FileResource extends Resource implements Touchable, FileProvider,
*/ */
public OutputStream getOutputStream() throws IOException { public OutputStream getOutputStream() throws IOException {
if (isReference()) { if (isReference()) {
return ((Resource) getCheckedRef()).getOutputStream();
return ((FileResource) getCheckedRef()).getOutputStream();
} }
return getOutputStream(false);
}

/**
* {@inheritDoc}
*/
public OutputStream getAppendOutputStream() throws IOException {
if (isReference()) {
return ((FileResource) getCheckedRef()).getAppendOutputStream();
}
return getOutputStream(true);
}

private OutputStream getOutputStream(boolean append) throws IOException {
File f = getNotNullFile(); File f = getNotNullFile();
if (f.exists()) { if (f.exists()) {
if (f.isFile()) {
if (f.isFile() && !append) {
f.delete(); f.delete();
} }
} else { } else {
@@ -222,7 +236,7 @@ public class FileResource extends Resource implements Touchable, FileProvider,
p.mkdirs(); p.mkdirs();
} }
} }
return new FileOutputStream(f);
return append ? new FileOutputStream(f.getAbsolutePath(), true) : new FileOutputStream(f);
} }


/** /**


+ 68
- 0
src/main/org/apache/tools/ant/types/resources/LogOutputResource.java View File

@@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.tools.ant.types.resources;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.taskdefs.LogOutputStream;
import org.apache.tools.ant.types.Resource;

/**
* Output-only Resource that always appends to Ant's log.
* @since Ant 1.8
*/
public class LogOutputResource extends Resource implements Appendable {
private static final String NAME = "[Ant log]";

private LogOutputStream outputStream;

/**
* Create a new LogOutputResource.
* @param managingComponent
*/
public LogOutputResource(ProjectComponent managingComponent) {
super(NAME);
outputStream = new LogOutputStream(managingComponent);
}

/**
* Create a new LogOutputResource.
* @param managingComponent owning log content
* @param level log level
*/
public LogOutputResource(ProjectComponent managingComponent, int level) {
super(NAME);
outputStream = new LogOutputStream(managingComponent, level);
}

/**
* {@inheritDoc}
*/
public OutputStream getAppendOutputStream() throws IOException {
return outputStream;
}

/**
* {@inheritDoc}
*/
public OutputStream getOutputStream() throws IOException {
return outputStream;
}
}

+ 42
- 5
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -469,15 +469,52 @@ public class FileUtils {
* *
* @since Ant 1.6 * @since Ant 1.6
*/ */
public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, Vector filterChains,
boolean overwrite, boolean preserveLastModified,
String inputEncoding, String outputEncoding,
Project project) throws IOException {
copyFile(sourceFile, destFile, filters, filterChains, overwrite, preserveLastModified,
false, inputEncoding, outputEncoding, project);
}

/**
* Convenience method to copy a file from a source to a
* destination specifying if token filtering must be used, if
* filter chains must be used, if source files may overwrite
* newer destination files and the last modified time of
* <code>destFile</code> file should be made equal
* to the last modified time of <code>sourceFile</code>.
*
* @param sourceFile the file to copy from.
* Must not be <code>null</code>.
* @param destFile the file to copy to.
* Must not be <code>null</code>.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination file should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the resulting file should be set to that
* of the source file.
* @param append whether to append to the destination file.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
*
*
* @throws IOException if the copying fails.
*
* @since Ant 1.8
*/
public void copyFile(File sourceFile, File destFile, public void copyFile(File sourceFile, File destFile,
FilterSetCollection filters, Vector filterChains, FilterSetCollection filters, Vector filterChains,
boolean overwrite, boolean preserveLastModified,
boolean overwrite, boolean preserveLastModified, boolean append,
String inputEncoding, String outputEncoding, String inputEncoding, String outputEncoding,
Project project) throws IOException { Project project) throws IOException {
ResourceUtils.copyResource(
new FileResource(sourceFile), new FileResource(destFile),
filters, filterChains, overwrite, preserveLastModified,
inputEncoding, outputEncoding, project);
ResourceUtils.copyResource(new FileResource(sourceFile), new FileResource(destFile),
filters, filterChains, overwrite, preserveLastModified, append, inputEncoding,
outputEncoding, project);
} }


// CheckStyle:ParameterNumberCheck ON // CheckStyle:ParameterNumberCheck ON


+ 61
- 15
src/main/org/apache/tools/ant/util/ResourceUtils.java View File

@@ -39,6 +39,7 @@ import org.apache.tools.ant.types.TimeComparison;
import org.apache.tools.ant.types.ResourceFactory; import org.apache.tools.ant.types.ResourceFactory;
import org.apache.tools.ant.types.ResourceCollection; import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.types.FilterSetCollection;
import org.apache.tools.ant.types.resources.Appendable;
import org.apache.tools.ant.types.resources.FileProvider; import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource; import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.ant.types.resources.Union; import org.apache.tools.ant.types.resources.Union;
@@ -265,12 +266,46 @@ public class ResourceUtils {
String inputEncoding, String outputEncoding, String inputEncoding, String outputEncoding,
Project project) Project project)
throws IOException { throws IOException {
if (!overwrite) {
long slm = source.getLastModified();
if (dest.isExists() && slm != 0
&& dest.getLastModified() > slm) {
return;
}
copyResource(source, dest, filters, filterChains, overwrite, preserveLastModified, false, inputEncoding, outputEncoding, project);
}

// CheckStyle:ParameterNumberCheck OFF - bc
/**
* Convenience method to copy content from one Resource to another
* specifying whether token filtering must be used, whether filter chains
* must be used, whether newer destination files may be overwritten and
* whether the last modified time of <code>dest</code> file should be made
* equal to the last modified time of <code>source</code>.
*
* @param source the Resource to copy from.
* Must not be <code>null</code>.
* @param dest the Resource to copy to.
* Must not be <code>null</code>.
* @param filters the collection of filters to apply to this copy.
* @param filterChains filterChains to apply during the copy.
* @param overwrite Whether or not the destination Resource should be
* overwritten if it already exists.
* @param preserveLastModified Whether or not the last modified time of
* the destination Resource should be set to that
* of the source.
* @param append Whether to append to an Appendable Resource.
* @param inputEncoding the encoding used to read the files.
* @param outputEncoding the encoding used to write the files.
* @param project the project instance.
*
* @throws IOException if the copying fails.
*
* @since Ant 1.8
*/
public static void copyResource(Resource source, Resource dest,
FilterSetCollection filters, Vector filterChains,
boolean overwrite, boolean preserveLastModified, boolean append,
String inputEncoding, String outputEncoding,
Project project)
throws IOException {
if (!(overwrite || SelectorUtils.isOutOfDate(source, dest, FileUtils.getFileUtils()
.getFileTimestampGranularity()))) {
return;
} }
final boolean filterSetsAvailable = (filters != null final boolean filterSetsAvailable = (filters != null
&& filters.hasFilters()); && filters.hasFilters());
@@ -288,12 +323,12 @@ public class ResourceUtils {
inputEncoding); inputEncoding);
} }
in = new BufferedReader(isr); in = new BufferedReader(isr);
OutputStreamWriter osw = null;
OutputStream os = getOutputStream(dest, append, project);
OutputStreamWriter osw;
if (outputEncoding == null) { if (outputEncoding == null) {
osw = new OutputStreamWriter(dest.getOutputStream());
osw = new OutputStreamWriter(os);
} else { } else {
osw = new OutputStreamWriter(dest.getOutputStream(),
outputEncoding);
osw = new OutputStreamWriter(os, outputEncoding);
} }
out = new BufferedWriter(osw); out = new BufferedWriter(osw);
if (filterChainsAvailable) { if (filterChainsAvailable) {
@@ -339,12 +374,12 @@ public class ResourceUtils {
inputEncoding); inputEncoding);
} }
in = new BufferedReader(isr); in = new BufferedReader(isr);
OutputStreamWriter osw = null;
OutputStream os = getOutputStream(dest, append, project);
OutputStreamWriter osw;
if (outputEncoding == null) { if (outputEncoding == null) {
osw = new OutputStreamWriter(dest.getOutputStream());
osw = new OutputStreamWriter(os);
} else { } else {
osw = new OutputStreamWriter(dest.getOutputStream(),
outputEncoding);
osw = new OutputStreamWriter(os, outputEncoding);
} }
out = new BufferedWriter(osw); out = new BufferedWriter(osw);
if (filterChainsAvailable) { if (filterChainsAvailable) {
@@ -373,7 +408,7 @@ public class ResourceUtils {
OutputStream out = null; OutputStream out = null;
try { try {
in = source.getInputStream(); in = source.getInputStream();
out = dest.getOutputStream();
out = getOutputStream(dest, append, project);


byte[] buffer = new byte[FileUtils.BUF_SIZE]; byte[] buffer = new byte[FileUtils.BUF_SIZE];
int count = 0; int count = 0;
@@ -587,4 +622,15 @@ public class ResourceUtils {
} }
} }


private static OutputStream getOutputStream(Resource resource, boolean append, Project project)
throws IOException {
if (append) {
if (resource instanceof Appendable) {
return ((Appendable) resource).getAppendOutputStream();
}
project.log("Appendable OutputStream not available for non-appendable resource "
+ resource + "; using plain OutputStream", Project.MSG_VERBOSE);
}
return resource.getOutputStream();
}
} }

+ 3
- 0
src/tests/antunit/taskdefs/echo-test.xml View File

@@ -86,6 +86,9 @@
<target name="testAppend"> <target name="testAppend">
<echo file="${output}/echo.txt">Simple text</echo> <echo file="${output}/echo.txt">Simple text</echo>
<echo file="${output}/echo.txt" append="true">Appended</echo> <echo file="${output}/echo.txt" append="true">Appended</echo>
<concat>
<file file="${output}/echo.txt" />
</concat>
<au:assertTrue> <au:assertTrue>
<resourcecount count="1"> <resourcecount count="1">
<restrict> <restrict>


Loading…
Cancel
Save