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)); + } }