|
|
@@ -212,34 +212,17 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* This class reads from each of the source files in turn. |
|
|
|
* The concatenated result can then be filtered as |
|
|
|
* a single stream. |
|
|
|
* This class reads a Reader and ensures it ends with the desired linebreak |
|
|
|
* @since Ant 1.10.10 |
|
|
|
*/ |
|
|
|
private final class MultiReader<S> extends Reader { |
|
|
|
private Reader reader = null; |
|
|
|
private int lastPos = 0; |
|
|
|
private char[] lastChars = new char[eolString.length()]; |
|
|
|
private final class LastLineFixingReader extends Reader { |
|
|
|
private final Reader reader; |
|
|
|
private int lastPos = 0; |
|
|
|
private final char[] lastChars = new char[eolString.length()]; |
|
|
|
private boolean needAddSeparator = false; |
|
|
|
private Iterator<S> readerSources; |
|
|
|
private ReaderFactory<S> factory; |
|
|
|
|
|
|
|
private MultiReader(Iterator<S> readerSources, ReaderFactory<S> factory) { |
|
|
|
this.readerSources = readerSources; |
|
|
|
this.factory = factory; |
|
|
|
} |
|
|
|
|
|
|
|
private Reader getReader() throws IOException { |
|
|
|
if (reader == null && readerSources.hasNext()) { |
|
|
|
reader = factory.getReader(readerSources.next()); |
|
|
|
Arrays.fill(lastChars, (char) 0); |
|
|
|
} |
|
|
|
return reader; |
|
|
|
} |
|
|
|
|
|
|
|
private void nextReader() throws IOException { |
|
|
|
close(); |
|
|
|
reader = null; |
|
|
|
private LastLineFixingReader(Reader reader) { |
|
|
|
this.reader = reader; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -253,25 +236,21 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
public int read() throws IOException { |
|
|
|
if (needAddSeparator) { |
|
|
|
if (lastPos >= eolString.length()) { |
|
|
|
lastPos = 0; |
|
|
|
needAddSeparator = false; |
|
|
|
return -1; |
|
|
|
} else { |
|
|
|
return eolString.charAt(lastPos++); |
|
|
|
} |
|
|
|
} |
|
|
|
while (getReader() != null) { |
|
|
|
int ch = getReader().read(); |
|
|
|
if (ch == -1) { |
|
|
|
nextReader(); |
|
|
|
if (isFixLastLine() && isMissingEndOfLine()) { |
|
|
|
needAddSeparator = true; |
|
|
|
lastPos = 1; |
|
|
|
return eolString.charAt(0); |
|
|
|
} |
|
|
|
} else { |
|
|
|
addLastChar((char) ch); |
|
|
|
return ch; |
|
|
|
int ch = reader.read(); |
|
|
|
if (ch == -1) { |
|
|
|
if (isMissingEndOfLine()) { |
|
|
|
needAddSeparator = true; |
|
|
|
lastPos = 1; |
|
|
|
return eolString.charAt(0); |
|
|
|
} |
|
|
|
} else { |
|
|
|
addLastChar((char) ch); |
|
|
|
return ch; |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
@@ -289,13 +268,12 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
int amountRead = 0; |
|
|
|
while (getReader() != null || needAddSeparator) { |
|
|
|
while (true) { |
|
|
|
if (needAddSeparator) { |
|
|
|
cbuf[off] = eolString.charAt(lastPos++); |
|
|
|
if (lastPos >= eolString.length()) { |
|
|
|
lastPos = 0; |
|
|
|
needAddSeparator = false; |
|
|
|
break; |
|
|
|
} |
|
|
|
cbuf[off] = eolString.charAt(lastPos++); |
|
|
|
len--; |
|
|
|
off++; |
|
|
|
amountRead++; |
|
|
@@ -304,23 +282,22 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
} |
|
|
|
continue; |
|
|
|
} |
|
|
|
int nRead = getReader().read(cbuf, off, len); |
|
|
|
int nRead = reader.read(cbuf, off, len); |
|
|
|
if (nRead == -1 || nRead == 0) { |
|
|
|
nextReader(); |
|
|
|
if (isFixLastLine() && isMissingEndOfLine()) { |
|
|
|
if (isMissingEndOfLine()) { |
|
|
|
needAddSeparator = true; |
|
|
|
lastPos = 0; |
|
|
|
} else { |
|
|
|
break; |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (isFixLastLine()) { |
|
|
|
for (int i = nRead; |
|
|
|
i > (nRead - lastChars.length); |
|
|
|
--i) { |
|
|
|
if (i <= 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
addLastChar(cbuf[off + i - 1]); |
|
|
|
for (int i = nRead; |
|
|
|
i > (nRead - lastChars.length); |
|
|
|
--i) { |
|
|
|
if (i <= 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
addLastChar(cbuf[off + i - 1]); |
|
|
|
} |
|
|
|
len -= nRead; |
|
|
|
off += nRead; |
|
|
@@ -341,9 +318,7 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public void close() throws IOException { |
|
|
|
if (reader != null) { |
|
|
|
reader.close(); |
|
|
|
} |
|
|
|
reader.close(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -367,6 +342,107 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* This class reads from each of the source files in turn. |
|
|
|
* The concatenated result can then be filtered as |
|
|
|
* a single stream. |
|
|
|
*/ |
|
|
|
private final class MultiReader<S> extends Reader { |
|
|
|
private Reader reader = null; |
|
|
|
private Iterator<S> readerSources; |
|
|
|
private ReaderFactory<S> factory; |
|
|
|
private final boolean filterBeforeConcat; |
|
|
|
|
|
|
|
private MultiReader(Iterator<S> readerSources, ReaderFactory<S> factory, |
|
|
|
boolean filterBeforeConcat) { |
|
|
|
this.readerSources = readerSources; |
|
|
|
this.factory = factory; |
|
|
|
this.filterBeforeConcat = filterBeforeConcat; |
|
|
|
} |
|
|
|
|
|
|
|
private Reader getReader() throws IOException { |
|
|
|
if (reader == null && readerSources.hasNext()) { |
|
|
|
reader = factory.getReader(readerSources.next()); |
|
|
|
if(isFixLastLine()) |
|
|
|
{ |
|
|
|
reader = new LastLineFixingReader(reader); |
|
|
|
} |
|
|
|
if(filterBeforeConcat) |
|
|
|
{ |
|
|
|
reader = getFilteredReader(reader); |
|
|
|
} |
|
|
|
} |
|
|
|
return reader; |
|
|
|
} |
|
|
|
|
|
|
|
private void nextReader() throws IOException { |
|
|
|
close(); |
|
|
|
reader = null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Read a character from the current reader object. Advance |
|
|
|
* to the next if the reader is finished. |
|
|
|
* @return the character read, -1 for EOF on the last reader. |
|
|
|
* @exception IOException - possibly thrown by the read for a reader |
|
|
|
* object. |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public int read() throws IOException { |
|
|
|
while (getReader() != null) { |
|
|
|
int ch = getReader().read(); |
|
|
|
if (ch == -1) { |
|
|
|
nextReader(); |
|
|
|
} else { |
|
|
|
return ch; |
|
|
|
} |
|
|
|
} |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Read into the buffer <code>cbuf</code>. |
|
|
|
* @param cbuf The array to be read into. |
|
|
|
* @param off The offset. |
|
|
|
* @param len The length to read. |
|
|
|
* @exception IOException - possibly thrown by the reads to the |
|
|
|
* reader objects. |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public int read(char[] cbuf, int off, int len) |
|
|
|
throws IOException { |
|
|
|
|
|
|
|
int amountRead = 0; |
|
|
|
while (getReader() != null) { |
|
|
|
int nRead = getReader().read(cbuf, off, len); |
|
|
|
if (nRead == -1 || nRead == 0) { |
|
|
|
nextReader(); |
|
|
|
} else { |
|
|
|
len -= nRead; |
|
|
|
off += nRead; |
|
|
|
amountRead += nRead; |
|
|
|
if (len == 0) { |
|
|
|
return amountRead; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (amountRead == 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
return amountRead; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Close the current reader |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public void close() throws IOException { |
|
|
|
if (reader != null) { |
|
|
|
reader.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private boolean isFixLastLine() { |
|
|
|
return fixLastLine && textBuffer == null; |
|
|
@@ -386,8 +462,14 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
result.setManagingComponent(this); |
|
|
|
return result; |
|
|
|
} |
|
|
|
Reader resourceReader = getFilteredReader( |
|
|
|
new MultiReader<>(c.iterator(), resourceReaderFactory)); |
|
|
|
Reader resourceReader; |
|
|
|
if(filterBeforeConcat) { |
|
|
|
resourceReader = new MultiReader<>(c.iterator(), |
|
|
|
resourceReaderFactory, true); |
|
|
|
} else { |
|
|
|
resourceReader = getFilteredReader( |
|
|
|
new MultiReader<>(c.iterator(), resourceReaderFactory, false)); |
|
|
|
} |
|
|
|
Reader rdr; |
|
|
|
if (header == null && footer == null) { |
|
|
|
rdr = resourceReader; |
|
|
@@ -416,7 +498,7 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
} |
|
|
|
} |
|
|
|
rdr = new MultiReader<>(Arrays.asList(readers).iterator(), |
|
|
|
identityReaderFactory); |
|
|
|
identityReaderFactory, false); |
|
|
|
} |
|
|
|
return outputEncoding == null ? new ReaderInputStream(rdr) |
|
|
|
: new ReaderInputStream(rdr, outputEncoding); |
|
|
@@ -454,6 +536,9 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
/** Stores the binary attribute */ |
|
|
|
private boolean binary; |
|
|
|
|
|
|
|
/** Stores the filterBeforeConcat attribute */ |
|
|
|
private boolean filterBeforeConcat; |
|
|
|
|
|
|
|
// Child elements. |
|
|
|
|
|
|
|
/** |
|
|
@@ -779,6 +864,17 @@ public class Concat extends Task implements ResourceCollection { |
|
|
|
this.binary = binary; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Set the filterBeforeConcat attribute. If true, concat will filter each |
|
|
|
* input through the filterchain before concatenating the results. This |
|
|
|
* allows to e.g. use the FileTokenizer to tokenize each input. |
|
|
|
* @param filterBeforeConcat if true, filter each input before concatenation |
|
|
|
* @since Ant 1.10.10 |
|
|
|
*/ |
|
|
|
public void setFilterBeforeConcat(final boolean filterBeforeConcat) { |
|
|
|
this.filterBeforeConcat = filterBeforeConcat; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Execute the concat task. |
|
|
|
*/ |
|
|
|