diff --git a/WHATSNEW b/WHATSNEW
index 66e7399a0..9e096c9d8 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -48,6 +48,11 @@ Other changes:
generated.
Bugzilla Report 62379
+ * The and nested elements of
+ and now support an encoding attribute that
+ can be used to specify the file's encoding.
+ Bugzilla Report 62379
+
Changes from Ant 1.9.10 TO Ant 1.9.11
=====================================
diff --git a/manual/Types/patternset.html b/manual/Types/patternset.html
index 4ad433dbc..1cfcb8f0b 100644
--- a/manual/Types/patternset.html
+++ b/manual/Types/patternset.html
@@ -125,6 +125,11 @@ you can use to test the existence of a property.
not set.
No |
+
+ encoding |
+ The encoding of the file. Since Ant 1.9.12 |
+ No, default is platform default |
+
patternset
Patternsets may be nested within one another, adding the nested
diff --git a/src/etc/testcases/types/fileset.xml b/src/etc/testcases/types/fileset.xml
new file mode 100644
index 000000000..c0f6949ff
--- /dev/null
+++ b/src/etc/testcases/types/fileset.xml
@@ -0,0 +1,40 @@
+
+
+
+
+ fileset.xml
+
+
+
+
+
+
+ ${property}
+
+
+
+ fileset.xml
+
+
+
+
+
+
+ ${property}
+
+
diff --git a/src/main/org/apache/tools/ant/taskdefs/Delete.java b/src/main/org/apache/tools/ant/taskdefs/Delete.java
index b22c7cc91..bf266a09c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Delete.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Delete.java
@@ -247,7 +247,7 @@ public class Delete extends MatchingTask {
/**
* add a name entry on the include files list
- * @return a NameEntry object to be configured
+ * @return a PatternFileNameEntry object to be configured
*/
public PatternSet.NameEntry createIncludesFile() {
usedMatchingTask = true;
@@ -265,7 +265,7 @@ public class Delete extends MatchingTask {
/**
* add a name entry on the include files list
- * @return a NameEntry object to be configured
+ * @return a PatternFileNameEntry object to be configured
*/
public PatternSet.NameEntry createExcludesFile() {
usedMatchingTask = true;
diff --git a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
index c35af03a2..8707a39a3 100644
--- a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
+++ b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
@@ -77,7 +77,7 @@ public abstract class MatchingTask extends Task implements SelectorContainer {
/**
* add a name entry on the include files list
- * @return an NameEntry object to be configured
+ * @return an PatternFileNameEntry object to be configured
*/
public PatternSet.NameEntry createIncludesFile() {
return fileset.createIncludesFile();
@@ -93,7 +93,7 @@ public abstract class MatchingTask extends Task implements SelectorContainer {
/**
* add a name entry on the include files list
- * @return an NameEntry object to be configured
+ * @return an PatternFileNameEntry object to be configured
*/
public PatternSet.NameEntry createExcludesFile() {
return fileset.createExcludesFile();
diff --git a/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
index 0c1d57d4e..1dca341c1 100644
--- a/src/main/org/apache/tools/ant/types/AbstractFileSet.java
+++ b/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -189,7 +189,7 @@ public abstract class AbstractFileSet extends DataType
/**
* Add a name entry to the include files list.
- * @return PatternSet.NameEntry
.
+ * @return PatternSet.PatternFileNameEntry
.
*/
public synchronized PatternSet.NameEntry createIncludesFile() {
if (isReference()) {
@@ -213,7 +213,7 @@ public abstract class AbstractFileSet extends DataType
/**
* Add a name entry to the excludes files list.
- * @return PatternSet.NameEntry
.
+ * @return PatternSet.PatternFileNameEntry
.
*/
public synchronized PatternSet.NameEntry createExcludesFile() {
if (isReference()) {
diff --git a/src/main/org/apache/tools/ant/types/PatternSet.java b/src/main/org/apache/tools/ant/types/PatternSet.java
index 9fb94050c..cd5797b2d 100644
--- a/src/main/org/apache/tools/ant/types/PatternSet.java
+++ b/src/main/org/apache/tools/ant/types/PatternSet.java
@@ -19,8 +19,10 @@ package org.apache.tools.ant.types;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
@@ -40,8 +42,8 @@ import org.apache.tools.ant.util.FileUtils;
public class PatternSet extends DataType implements Cloneable {
private List includeList = new ArrayList();
private List excludeList = new ArrayList();
- private List includesFileList = new ArrayList();
- private List excludesFileList = new ArrayList();
+ private List includesFileList = new ArrayList();
+ private List excludesFileList = new ArrayList();
/**
* inner class to hold a name on list. "If" and "Unless" attributes
@@ -176,6 +178,45 @@ public class PatternSet extends DataType implements Cloneable {
}
}
+ /**
+ * Adds encoding support to {@link NameEntry}.
+ * @since Ant 1.9.12
+ */
+ public class PatternFileNameEntry extends NameEntry {
+ private String encoding;
+
+ /**
+ * Encoding to use when reading the file, defaults to the platform's default
+ * encoding.
+ *
+ *
+ * For a list of possible values see
+ *
+ * https://docs.oracle.com/javase/1.5.0/docs/guide/intl/encoding.doc.html.
+ *
+ *
+ * @param encoding String
+ */
+ public final void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Encoding to use when reading the file, defaults to the platform's default
+ * encoding.
+ */
+ public final String getEncoding() {
+ return encoding;
+ }
+
+ @Override
+ public String toString() {
+ String baseString = super.toString();
+ return encoding == null ? baseString
+ : new StringBuilder(baseString).append(";encoding->").append(encoding).toString();
+ }
+ }
+
private static final class InvertedPatternSet extends PatternSet {
private InvertedPatternSet(PatternSet p) {
setProject(p.getProject());
@@ -255,7 +296,7 @@ public class PatternSet extends DataType implements Cloneable {
if (isReference()) {
throw noChildrenAllowed();
}
- return addPatternToList(includesFileList);
+ return addPatternFileToList(includesFileList);
}
/**
@@ -277,7 +318,7 @@ public class PatternSet extends DataType implements Cloneable {
if (isReference()) {
throw noChildrenAllowed();
}
- return addPatternToList(excludesFileList);
+ return addPatternFileToList(excludesFileList);
}
/**
@@ -325,6 +366,15 @@ public class PatternSet extends DataType implements Cloneable {
return result;
}
+ /**
+ * add a pattern file name entry to the given list
+ */
+ private PatternFileNameEntry addPatternFileToList(List list) {
+ PatternFileNameEntry result = new PatternFileNameEntry();
+ list.add(result);
+ return result;
+ }
+
/**
* Sets the name of the file containing the includes patterns.
*
@@ -355,13 +405,17 @@ public class PatternSet extends DataType implements Cloneable {
* Reads path matching patterns from a file and adds them to the
* includes or excludes list (as appropriate).
*/
- private void readPatterns(File patternfile, List patternlist, Project p)
+ private void readPatterns(File patternfile, String encoding, List patternlist, Project p)
throws BuildException {
BufferedReader patternReader = null;
try {
// Get a FileReader
- patternReader = new BufferedReader(new FileReader(patternfile));
+ if (encoding == null) {
+ patternReader = new BufferedReader(new FileReader(patternfile));
+ } else {
+ patternReader = new BufferedReader(new InputStreamReader(new FileInputStream(patternfile), encoding));
+ }
// Create one NameEntry in the appropriate pattern list for each
// line in the file.
@@ -478,7 +532,7 @@ public class PatternSet extends DataType implements Cloneable {
*/
private void readFiles(Project p) {
if (includesFileList.size() > 0) {
- for (NameEntry ne : includesFileList) {
+ for (PatternFileNameEntry ne : includesFileList) {
String fileName = ne.evalName(p);
if (fileName != null) {
File inclFile = p.resolveFile(fileName);
@@ -486,13 +540,13 @@ public class PatternSet extends DataType implements Cloneable {
throw new BuildException("Includesfile " + inclFile.getAbsolutePath()
+ " not found.");
}
- readPatterns(inclFile, includeList, p);
+ readPatterns(inclFile, ne.getEncoding(), includeList, p);
}
}
includesFileList.clear();
}
if (excludesFileList.size() > 0) {
- for (NameEntry ne : excludesFileList) {
+ for (PatternFileNameEntry ne : excludesFileList) {
String fileName = ne.evalName(p);
if (fileName != null) {
File exclFile = p.resolveFile(fileName);
@@ -500,7 +554,7 @@ public class PatternSet extends DataType implements Cloneable {
throw new BuildException("Excludesfile " + exclFile.getAbsolutePath()
+ " not found.");
}
- readPatterns(exclFile, excludeList, p);
+ readPatterns(exclFile, ne.getEncoding(), excludeList, p);
}
}
excludesFileList.clear();
@@ -523,8 +577,8 @@ public class PatternSet extends DataType implements Cloneable {
PatternSet ps = (PatternSet) super.clone();
ps.includeList = new ArrayList(includeList);
ps.excludeList = new ArrayList(excludeList);
- ps.includesFileList = new ArrayList(includesFileList);
- ps.excludesFileList = new ArrayList(excludesFileList);
+ ps.includesFileList = new ArrayList(includesFileList);
+ ps.excludesFileList = new ArrayList(excludesFileList);
return ps;
} catch (CloneNotSupportedException e) {
throw new BuildException(e);
diff --git a/src/main/org/apache/tools/ant/types/resources/Files.java b/src/main/org/apache/tools/ant/types/resources/Files.java
index 521bcc8d2..a28e3a75c 100644
--- a/src/main/org/apache/tools/ant/types/resources/Files.java
+++ b/src/main/org/apache/tools/ant/types/resources/Files.java
@@ -124,7 +124,7 @@ public class Files extends AbstractSelectorContainer
/**
* Add a name entry to the include files list.
- * @return PatternSet.NameEntry
.
+ * @return PatternSet.PatternFileNameEntry
.
*/
public synchronized PatternSet.NameEntry createIncludesFile() {
if (isReference()) {
@@ -148,7 +148,7 @@ public class Files extends AbstractSelectorContainer
/**
* Add a name entry to the excludes files list.
- * @return PatternSet.NameEntry
.
+ * @return PatternSet.PatternFileNameEntry
.
*/
public synchronized PatternSet.NameEntry createExcludesFile() {
if (isReference()) {
diff --git a/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java b/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java
index e5aa8758f..3ca5faa46 100644
--- a/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java
@@ -18,17 +18,41 @@
package org.apache.tools.ant.types;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
/**
* JUnit 4 testcases for org.apache.tools.ant.types.FileSet.
- *
- * This doesn't actually test much, mainly reference handling.
*/
public class FileSetTest extends AbstractFileSetTest {
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void buildFileRuleSetUp() {
+ buildRule.configureProject("src/etc/testcases/types/fileset.xml");
+ }
+
protected AbstractFileSet getInstance() {
return new FileSet();
}
+ @Test
+ public void testNoEncoding() {
+ buildRule.executeTarget("no-encoding");
+ assertEquals("/abc/fileset.xml", buildRule.getLog());
+ }
+
+ @Test
+ public void testEncoding() {
+ buildRule.executeTarget("encoding");
+ assertEquals("/abc/fileset.xml", buildRule.getLog());
+ }
+
}
diff --git a/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java b/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java
index a4f27b0ce..6baecbb89 100644
--- a/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java
+++ b/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java
@@ -20,11 +20,18 @@ package org.apache.tools.ant.types;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -202,4 +209,26 @@ public class PatternSetTest {
assertEquals("Includes", "**/*.java", includes[0]);
assertEquals("Excludes", "**/*.class", excludes[0]);
}
+
+ @Test
+ public void testEncodingOfIncludesFile() throws IOException {
+ File testFile = File.createTempFile("ant-", ".pattern");
+ testFile.deleteOnExit();
+ OutputStream o = null;
+ Writer w = null;
+ try {
+ o = new FileOutputStream(testFile);
+ w = new OutputStreamWriter(o, "UTF-16LE");
+ w.write("\u00e4\n");
+ } finally {
+ FileUtils.close(w);
+ FileUtils.close(o);
+ }
+ PatternSet p = new PatternSet();
+ PatternSet.PatternFileNameEntry ne =
+ (PatternSet.PatternFileNameEntry) p.createIncludesFile();
+ ne.setName(testFile.getAbsolutePath());
+ ne.setEncoding("UTF-16LE");
+ assertArrayEquals(new String[] { "\u00e4" }, p.getIncludePatterns(project));
+ }
}