aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java199
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java218
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java142
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java1004
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java222
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java164
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java379
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java375
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java174
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java243
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java712
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java288
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java70
25 files changed, 5852 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java
new file mode 100644
index 00000000..3b3b0270
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java
@@ -0,0 +1,199 @@
+/*
+ * 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.filters;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Base class for core filter readers.
+ *
+ */
+public abstract class BaseFilterReader extends FilterReader {
+ /** Buffer size used when reading */
+ private static final int BUFFER_SIZE = 8192;
+
+ /** Have the parameters passed been interpreted? */
+ private boolean initialized = false;
+
+ /** The Ant project this filter is part of. */
+ private Project project = null;
+
+ /**
+ * Constructor used by Ant's introspection mechanism.
+ * The original filter reader is only used for chaining
+ * purposes, never for filtering purposes (and indeed
+ * it would be useless for filtering purposes, as it has
+ * no real data to filter). ChainedReaderHelper uses
+ * this placeholder instance to create a chain of real filters.
+ */
+ public BaseFilterReader() {
+ super(new StringReader(""));
+ FileUtils.close(this);
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ */
+ public BaseFilterReader(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Reads characters into a portion of an array. This method will block
+ * until some input is available, an I/O error occurs, or the end of the
+ * stream is reached.
+ *
+ * @param cbuf Destination buffer to write characters to.
+ * Must not be <code>null</code>.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ *
+ * @return the number of characters read, or -1 if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public final int read(final char[] cbuf, final int off,
+ final int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ final int ch = read();
+ if (ch == -1) {
+ if (i == 0) {
+ return -1;
+ } else {
+ return i;
+ }
+ }
+ cbuf[off + i] = (char) ch;
+ }
+ return len;
+ }
+
+ /**
+ * Skips characters. This method will block until some characters are
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return the number of characters actually skipped
+ *
+ * @exception IllegalArgumentException If <code>n</code> is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public final long skip(final long n)
+ throws IOException, IllegalArgumentException {
+ if (n < 0L) {
+ throw new IllegalArgumentException("skip value is negative");
+ }
+
+ for (long i = 0; i < n; i++) {
+ if (read() == -1) {
+ return i;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Sets the initialized status.
+ *
+ * @param initialized Whether or not the filter is initialized.
+ */
+ protected final void setInitialized(final boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ /**
+ * Returns the initialized status.
+ *
+ * @return whether or not the filter is initialized
+ */
+ protected final boolean getInitialized() {
+ return initialized;
+ }
+
+ /**
+ * Sets the project to work with.
+ *
+ * @param project The project this filter is part of.
+ * Should not be <code>null</code>.
+ */
+ public final void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Returns the project this filter is part of.
+ *
+ * @return the project this filter is part of
+ */
+ protected final Project getProject() {
+ return project;
+ }
+
+ /**
+ * Reads a line of text ending with '\n' (or until the end of the stream).
+ * The returned String retains the '\n'.
+ *
+ * @return the line read, or <code>null</code> if the end of the stream
+ * has already been reached
+ *
+ * @exception IOException if the underlying reader throws one during
+ * reading
+ */
+ protected final String readLine() throws IOException {
+ int ch = in.read();
+
+ if (ch == -1) {
+ return null;
+ }
+
+ StringBuffer line = new StringBuffer();
+
+ while (ch != -1) {
+ line.append ((char) ch);
+ if (ch == '\n') {
+ break;
+ }
+ ch = in.read();
+ }
+ return line.toString();
+ }
+
+ /**
+ * Reads to the end of the stream, returning the contents as a String.
+ *
+ * @return the remaining contents of the reader, as a String
+ *
+ * @exception IOException if the underlying reader throws one during
+ * reading
+ */
+ protected final String readFully() throws IOException {
+ return FileUtils.readFully(in, BUFFER_SIZE);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java
new file mode 100644
index 00000000..54bc9ff9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java
@@ -0,0 +1,74 @@
+/*
+ * 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.filters;
+
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Parameterizable;
+
+/**
+ * Parameterized base class for core filter readers.
+ *
+ */
+public abstract class BaseParamFilterReader
+ extends BaseFilterReader
+ implements Parameterizable {
+ /** The passed in parameter array. */
+ private Parameter[] parameters;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public BaseParamFilterReader() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public BaseParamFilterReader(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Sets the parameters used by this filter, and sets
+ * the filter to an uninitialized status.
+ *
+ * @param parameters The parameters to be used by this filter.
+ * Should not be <code>null</code>.
+ */
+ public final void setParameters(final Parameter[] parameters) {
+ this.parameters = parameters;
+ setInitialized(false);
+ }
+
+ /**
+ * Returns the parameters to be used by this filter.
+ *
+ * @return the parameters to be used by this filter
+ */
+ protected final Parameter[] getParameters() {
+ return parameters;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java
new file mode 100644
index 00000000..67060393
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java
@@ -0,0 +1,37 @@
+/*
+ * 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.filters;
+
+import java.io.Reader;
+
+/**
+ * Interface indicating that a reader may be chained to another one.
+ *
+ */
+public interface ChainableReader {
+ /**
+ * Returns a reader with the same configuration as this one,
+ * but filtering input from the specified reader.
+ *
+ * @param rdr the reader which the returned reader should be filtering
+ *
+ * @return a reader with the same configuration as this one, but
+ * filtering input from the specified reader
+ */
+ Reader chain(Reader rdr);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java
new file mode 100644
index 00000000..35443012
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java
@@ -0,0 +1,165 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Assembles the constants declared in a Java class in
+ * <code>key1=value1(line separator)key2=value2</code>
+ * format.
+ *<p>
+ * Notes:
+ * <ol>
+ * <li>This filter uses the BCEL external toolkit.
+ * <li>This assembles only those constants that are not created
+ * using the syntax <code>new whatever()</code>
+ * <li>This assembles constants declared using the basic datatypes
+ * and String only.</li>
+ * <li>The access modifiers of the declared constants do not matter.</li>
+ *</ol>
+ * Example:<br>
+ * <pre>&lt;classconstants/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.ClassConstants&quot;/&gt;</pre>
+ */
+public final class ClassConstants
+ extends BaseFilterReader
+ implements ChainableReader {
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /** Helper Class to be invoked via reflection. */
+ private static final String JAVA_CLASS_HELPER =
+ "org.apache.tools.ant.filters.util.JavaClassHelper";
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ClassConstants() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader. The contents of the passed-in reader
+ * are expected to be the name of the class from which to produce a
+ * list of constants.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ClassConstants(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Reads and assembles the constants declared in a class file.
+ *
+ * @return the next character in the list of constants, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading, or if the constants for the specified class cannot
+ * be read (for example due to the class not being found).
+ */
+ public int read() throws IOException {
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ final String clazz = readFully();
+ if (clazz == null || clazz.length() == 0) {
+ ch = -1;
+ } else {
+ final byte[] bytes = clazz.getBytes(ResourceUtils.ISO_8859_1);
+ try {
+ final Class<?> javaClassHelper =
+ Class.forName(JAVA_CLASS_HELPER);
+ if (javaClassHelper != null) {
+ final Class<?>[] params = {
+ byte[].class
+ };
+ final Method getConstants =
+ javaClassHelper.getMethod("getConstants", params);
+ final Object[] args = {
+ bytes
+ };
+ // getConstants is a static method, no need to
+ // pass in the object
+ final StringBuffer sb = (StringBuffer)
+ getConstants.invoke(null, args);
+ if (sb.length() > 0) {
+ queuedData = sb.toString();
+ return read();
+ }
+ }
+ } catch (NoClassDefFoundError ex) {
+ throw ex;
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (InvocationTargetException ex) {
+ Throwable t = ex.getTargetException();
+ if (t instanceof NoClassDefFoundError) {
+ throw (NoClassDefFoundError) t;
+ }
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ }
+ throw new BuildException(t);
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new ClassConstants using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ClassConstants newFilter = new ClassConstants(rdr);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java
new file mode 100644
index 00000000..0ac6024b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java
@@ -0,0 +1,218 @@
+/*
+ * 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.filters;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Concats a file before and/or after the file.
+ *
+ * <p>Example:</p><pre>
+ * &lt;copy todir="build"&gt;
+ * &lt;fileset dir="src" includes="*.java"/&gt;
+ * &lt;filterchain&gt;
+ * &lt;concatfilter prepend="apache-license-java.txt"/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>Copies all java sources from <i>src</i> to <i>build</i> and adds the
+ * content of <i>apache-license-java.txt</i> add the beginning of each
+ * file.</p>
+ *
+ * @since 1.6
+ * @version 2003-09-23
+ */
+public final class ConcatFilter extends BaseParamFilterReader
+ implements ChainableReader {
+
+ /** File to add before the content. */
+ private File prepend;
+
+ /** File to add after the content. */
+ private File append;
+
+ /** Reader for prepend-file. */
+ private Reader prependReader = null;
+
+ /** Reader for append-file. */
+ private Reader appendReader = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ConcatFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ConcatFilter(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired
+ * number of lines have already been read, the resulting stream is
+ * effectively at an end. Otherwise, the next character from the
+ * underlying stream is read and returned.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ @Override
+ public int read() throws IOException {
+ // do the "singleton" initialization
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ // The readers return -1 if they end. So simply read the "prepend"
+ // after that the "content" and at the end the "append" file.
+ if (prependReader != null) {
+ ch = prependReader.read();
+ if (ch == -1) {
+ // I am the only one so I have to close the reader
+ prependReader.close();
+ prependReader = null;
+ }
+ }
+ if (ch == -1) {
+ ch = super.read();
+ }
+ if (ch == -1) {
+ // don't call super.close() because that reader is used
+ // on other places ...
+ if (appendReader != null) {
+ ch = appendReader.read();
+ if (ch == -1) {
+ // I am the only one so I have to close the reader
+ appendReader.close();
+ appendReader = null;
+ }
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Sets <i>prepend</i> attribute.
+ * @param prepend new value
+ */
+ public void setPrepend(final File prepend) {
+ this.prepend = prepend;
+ }
+
+ /**
+ * Returns <i>prepend</i> attribute.
+ * @return prepend attribute
+ */
+ public File getPrepend() {
+ return prepend;
+ }
+
+ /**
+ * Sets <i>append</i> attribute.
+ * @param append new value
+ */
+ public void setAppend(final File append) {
+ this.append = append;
+ }
+
+ /**
+ * Returns <i>append</i> attribute.
+ * @return append attribute
+ */
+ public File getAppend() {
+ return append;
+ }
+
+ /**
+ * Creates a new ConcatReader using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ final ConcatFilter newFilter = new ConcatFilter(rdr);
+ newFilter.setPrepend(getPrepend());
+ newFilter.setAppend(getAppend());
+ // Usually the initialized is set to true. But here it must not.
+ // Because the prepend and append readers have to be instantiated
+ // on runtime
+ //newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for skip parameter.
+ */
+ private void initialize() throws IOException {
+ // get parameters
+ final Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if ("prepend".equals(params[i].getName())) {
+ setPrepend(new File(params[i].getValue()));
+ continue;
+ }
+ if ("append".equals(params[i].getName())) {
+ setAppend(new File(params[i].getValue()));
+ continue;
+ }
+ }
+ }
+ if (prepend != null) {
+ if (!prepend.isAbsolute()) {
+ prepend = new File(getProject().getBaseDir(), prepend.getPath());
+ }
+ prependReader = new BufferedReader(new FileReader(prepend));
+ }
+ if (append != null) {
+ if (!append.isAbsolute()) {
+ append = new File(getProject().getBaseDir(), append.getPath());
+ }
+ appendReader = new BufferedReader(new FileReader(append));
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java
new file mode 100644
index 00000000..dd454395
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java
@@ -0,0 +1,123 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.util.UnicodeUtil;
+
+/**
+ * This method converts non-latin characters to unicode escapes.
+ * Useful to load properties containing non latin
+ * Example:
+ *
+ * <pre>&lt;escapeunicode&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ classname=&quot;org.apache.tools.ant.filters.EscapeUnicode&quot;/&gt;
+ * </pre>
+ *
+ * @since Ant 1.6
+ */
+public class EscapeUnicode
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ //this field will hold unnnn right after reading a non latin character
+ //afterwards it will be truncated of one char every call to read
+ private StringBuffer unicodeBuf;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public EscapeUnicode() {
+ super();
+ unicodeBuf = new StringBuffer();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public EscapeUnicode(final Reader in) {
+ super(in);
+ unicodeBuf = new StringBuffer();
+ }
+
+ /**
+ * Returns the next character in the filtered stream, converting non latin
+ * characters to unicode escapes.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws
+ * an IOException during reading
+ */
+ public final int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+ if (unicodeBuf.length() == 0) {
+ ch = in.read();
+ if (ch != -1) {
+ char achar = (char) ch;
+ if (achar >= '\u0080') {
+ unicodeBuf = UnicodeUtil.EscapeUnicode(achar);
+ ch = '\\';
+ }
+ }
+ } else {
+ ch = (int) unicodeBuf.charAt(0);
+ unicodeBuf.deleteCharAt(0);
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new EscapeUnicode using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public final Reader chain(final Reader rdr) {
+ EscapeUnicode newFilter = new EscapeUnicode(rdr);
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters (currently unused)
+ */
+ private void initialize() {
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java
new file mode 100644
index 00000000..524a799b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java
@@ -0,0 +1,142 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.property.GetProperty;
+import org.apache.tools.ant.property.ParseProperties;
+import org.apache.tools.ant.types.PropertySet;
+
+/**
+ * Expands Ant properties, if any, in the data.
+ * <p>
+ * Example:<br>
+ * <pre>&lt;expandproperties/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.ExpandProperties&quot;/&gt;</pre>
+ *
+ */
+public final class ExpandProperties
+ extends BaseFilterReader
+ implements ChainableReader {
+
+ private static final int EOF = -1;
+
+ private char[] buffer;
+ private int index;
+ private PropertySet propertySet;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ExpandProperties() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ExpandProperties(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Restrict the expanded properties using a PropertySet.
+ * @param propertySet replacement lookup
+ */
+ public void add(PropertySet propertySet) {
+ if (this.propertySet != null) {
+ throw new BuildException("expandproperties filter accepts only one propertyset");
+ }
+ this.propertySet = propertySet;
+ }
+
+ /**
+ * Returns the next character in the filtered stream. The original
+ * stream is first read in fully, and the Ant properties are expanded.
+ * The results of this expansion are then queued so they can be read
+ * character-by-character.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (index > EOF) {
+ if (buffer == null) {
+ String data = readFully();
+ Project project = getProject();
+ GetProperty getProperty;
+ if (propertySet == null) {
+ getProperty = PropertyHelper.getPropertyHelper(project);
+ } else {
+ final Properties props = propertySet.getProperties();
+ getProperty = new GetProperty() {
+
+ public Object getProperty(String name) {
+ return props.getProperty(name);
+ }
+ };
+ }
+ Object expanded = new ParseProperties(project, PropertyHelper
+ .getPropertyHelper(project)
+ .getExpanders(),
+ getProperty)
+ .parseProperties(data);
+ buffer = expanded == null ? new char[0]
+ : expanded.toString().toCharArray();
+ }
+ if (index < buffer.length) {
+ return buffer[index++];
+ }
+ index = EOF;
+ }
+ return EOF;
+ }
+
+ /**
+ * Creates a new ExpandProperties filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ExpandProperties newFilter = new ExpandProperties(rdr);
+ newFilter.setProject(getProject());
+ newFilter.add(propertySet);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java
new file mode 100644
index 00000000..8a37924c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java
@@ -0,0 +1,1004 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Converts text to local OS formatting conventions, as well as repair text
+ * damaged by misconfigured or misguided editors or file transfer programs.
+ * <p>
+ * This filter can take the following arguments:
+ * <ul>
+ * <li>eof
+ * <li>eol
+ * <li>fixlast
+ * <li>javafiles
+ * <li>tab
+ * <li>tablength
+ * </ul>
+ * None of which are required.
+ * <p>
+ * This version generalises the handling of EOL characters, and allows for
+ * CR-only line endings (the standard on Mac systems prior to OS X). Tab
+ * handling has also been generalised to accommodate any tabwidth from 2 to 80,
+ * inclusive. Importantly, it can leave untouched any literal TAB characters
+ * embedded within Java string or character constants.
+ * <p>
+ * <em>Caution:</em> run with care on carefully formatted files. This may
+ * sound obvious, but if you don't specify asis, presume that your files are
+ * going to be modified. If "tabs" is "add" or "remove", whitespace characters
+ * may be added or removed as necessary. Similarly, for EOLs, eol="asis"
+ * actually means convert to your native O/S EOL convention while eol="crlf" or
+ * cr="add" can result in CR characters being removed in one special case
+ * accommodated, i.e., CRCRLF is regarded as a single EOL to handle cases where
+ * other programs have converted CRLF into CRCRLF.
+ *
+ * <P>
+ * Example:
+ *
+ * <pre>
+ * &lt;&lt;fixcrlf tab=&quot;add&quot; eol=&quot;crlf&quot; eof=&quot;asis&quot;/&gt;
+ * </pre>
+ *
+ * Or:
+ *
+ * <pre>
+ * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.FixCrLfFilter&quot;&gt;
+ * &lt;param eol=&quot;crlf&quot; tab=&quot;asis&quot;/&gt;
+ * &lt;/filterreader&gt;
+ * </pre>
+ *
+ */
+public final class FixCrLfFilter extends BaseParamFilterReader implements ChainableReader {
+ private static final int DEFAULT_TAB_LENGTH = 8;
+ private static final int MIN_TAB_LENGTH = 2;
+ private static final int MAX_TAB_LENGTH = 80;
+ private static final char CTRLZ = '\u001A';
+
+ private int tabLength = DEFAULT_TAB_LENGTH;
+
+ private CrLf eol;
+
+ private AddAsisRemove ctrlz;
+
+ private AddAsisRemove tabs;
+
+ private boolean javafiles = false;
+
+ private boolean fixlast = true;
+
+ private boolean initialized = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public FixCrLfFilter() {
+ super();
+ }
+
+ /**
+ * Create a new filtered reader.
+ *
+ * @param in
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ * @throws IOException on error.
+ */
+ public FixCrLfFilter(final Reader in) throws IOException {
+ super(in);
+ }
+
+ // Instance initializer: Executes just after the super() call in this
+ // class's constructor.
+ {
+ tabs = AddAsisRemove.ASIS;
+ if (Os.isFamily("mac") && !Os.isFamily("unix")) {
+ ctrlz = AddAsisRemove.REMOVE;
+ setEol(CrLf.MAC);
+ } else if (Os.isFamily("dos")) {
+ ctrlz = AddAsisRemove.ASIS;
+ setEol(CrLf.DOS);
+ } else {
+ ctrlz = AddAsisRemove.REMOVE;
+ setEol(CrLf.UNIX);
+ }
+ }
+
+ /**
+ * Create a new FixCrLfFilter using the passed in Reader for instantiation.
+ *
+ * @param rdr
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering the
+ * specified reader.
+ */
+ public Reader chain(final Reader rdr) {
+ try {
+ FixCrLfFilter newFilter = new FixCrLfFilter(rdr);
+
+ newFilter.setJavafiles(getJavafiles());
+ newFilter.setEol(getEol());
+ newFilter.setTab(getTab());
+ newFilter.setTablength(getTablength());
+ newFilter.setEof(getEof());
+ newFilter.setFixlast(getFixlast());
+ newFilter.initInternalFilters();
+
+ return newFilter;
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Get how DOS EOF (control-z) characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>add: ensure that there is an eof at the end of the file
+ * <li>asis: leave eof characters alone
+ * <li>remove: remove any eof character found at the end
+ * </ul>
+ */
+ public AddAsisRemove getEof() {
+ // Return copy so that the call must call setEof() to change the state
+ // of fixCRLF
+ return ctrlz.newInstance();
+ }
+
+ /**
+ * Get how EndOfLine characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>asis: convert line endings to your O/S convention
+ * <li>cr: convert line endings to CR
+ * <li>lf: convert line endings to LF
+ * <li>crlf: convert line endings to CRLF
+ * </ul>
+ */
+ public CrLf getEol() {
+ // Return copy so that the call must call setEol() to change the state
+ // of fixCRLF
+ return eol.newInstance();
+ }
+
+ /**
+ * Get whether a missing EOL be added to the final line of the stream.
+ *
+ * @return true if a filtered file will always end with an EOL
+ */
+ public boolean getFixlast() {
+ return fixlast;
+ }
+
+ /**
+ * Get whether the stream is to be treated as though it contains Java
+ * source.
+ * <P>
+ * This attribute is only used in association with the &quot;<i><b>tab</b></i>&quot;
+ * attribute. Tabs found in Java literals are protected from changes by this
+ * filter.
+ *
+ * @return true if whitespace in Java character and string literals is
+ * ignored.
+ */
+ public boolean getJavafiles() {
+ return javafiles;
+ }
+
+ /**
+ * Return how tab characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>add: convert sequences of spaces which span a tab stop to
+ * tabs
+ * <li>asis: leave tab and space characters alone
+ * <li>remove: convert tabs to spaces
+ * </ul>
+ */
+ public AddAsisRemove getTab() {
+ // Return copy so that the caller must call setTab() to change the state
+ // of fixCRLF.
+ return tabs.newInstance();
+ }
+
+ /**
+ * Get the tab length to use.
+ *
+ * @return the length of tab in spaces
+ */
+ public int getTablength() {
+ return tabLength;
+ }
+
+ private static String calculateEolString(CrLf eol) {
+ // Calculate the EOL string per the current config
+ if (eol == CrLf.CR || eol == CrLf.MAC) {
+ return "\r";
+ }
+ if (eol == CrLf.CRLF || eol == CrLf.DOS) {
+ return "\r\n";
+ }
+ // assume (eol == CrLf.LF || eol == CrLf.UNIX)
+ return "\n";
+ }
+
+ /**
+ * Wrap the input stream with the internal filters necessary to perform the
+ * configuration settings.
+ */
+ private void initInternalFilters() {
+
+ // If I'm removing an EOF character, do so first so that the other
+ // filters don't see that character.
+ in = (ctrlz == AddAsisRemove.REMOVE) ? new RemoveEofFilter(in) : in;
+
+ // Change all EOL characters to match the calculated EOL string. If
+ // configured to do so, append a trailing EOL so that the file ends on
+ // a EOL.
+ if (eol != CrLf.ASIS) {
+ in = new NormalizeEolFilter(in, calculateEolString(eol), getFixlast());
+ }
+
+ if (tabs != AddAsisRemove.ASIS) {
+ // If filtering Java source, prevent changes to whitespace in
+ // character and string literals.
+ if (getJavafiles()) {
+ in = new MaskJavaTabLiteralsFilter(in);
+ }
+ // Add/Remove tabs
+ in = (tabs == AddAsisRemove.ADD) ? (Reader) new AddTabFilter(in, getTablength())
+ : (Reader) new RemoveTabFilter(in, getTablength());
+ }
+ // Add missing EOF character
+ in = (ctrlz == AddAsisRemove.ADD) ? new AddEofFilter(in) : in;
+ initialized = true;
+ }
+
+ /**
+ * Return the next character in the filtered stream.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
+ * the resulting stream has been reached.
+ *
+ * @exception IOException
+ * if the underlying stream throws an IOException during
+ * reading.
+ */
+ public synchronized int read() throws IOException {
+ if (!initialized) {
+ initInternalFilters();
+ }
+ return in.read();
+ }
+
+ /**
+ * Specify how DOS EOF (control-z) characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>add: ensure that there is an eof at the end of the file
+ * <li>asis: leave eof characters alone
+ * <li>remove: remove any eof character found at the end
+ * </ul>
+ */
+ public void setEof(AddAsisRemove attr) {
+ ctrlz = attr.resolve();
+ }
+
+ /**
+ * Specify how end of line (EOL) characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>asis: convert line endings to your O/S convention
+ * <li>cr: convert line endings to CR
+ * <li>lf: convert line endings to LF
+ * <li>crlf: convert line endings to CRLF
+ * </ul>
+ */
+ public void setEol(CrLf attr) {
+ eol = attr.resolve();
+ }
+
+ /**
+ * Specify whether a missing EOL will be added to the final line of input.
+ *
+ * @param fixlast
+ * if true a missing EOL will be appended.
+ */
+ public void setFixlast(boolean fixlast) {
+ this.fixlast = fixlast;
+ }
+
+ /**
+ * Indicate whether this stream contains Java source.
+ *
+ * This attribute is only used in association with the &quot;<i><b>tab</b></i>&quot;
+ * attribute.
+ *
+ * @param javafiles
+ * set to true to prevent this filter from changing tabs found in
+ * Java literals.
+ */
+ public void setJavafiles(boolean javafiles) {
+ this.javafiles = javafiles;
+ }
+
+ /**
+ * Specify how tab characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>add: convert sequences of spaces which span a tab stop to
+ * tabs
+ * <li>asis: leave tab and space characters alone
+ * <li>remove: convert tabs to spaces
+ * </ul>
+ */
+ public void setTab(AddAsisRemove attr) {
+ tabs = attr.resolve();
+ }
+
+ /**
+ * Specify tab length in characters.
+ *
+ * @param tabLength
+ * specify the length of tab in spaces. Valid values are between
+ * 2 and 80 inclusive. The default for this parameter is 8.
+ * @throws IOException on error.
+ */
+ public void setTablength(int tabLength) throws IOException {
+ if (tabLength < MIN_TAB_LENGTH
+ || tabLength > MAX_TAB_LENGTH) {
+ throw new IOException(
+ "tablength must be between " + MIN_TAB_LENGTH
+ + " and " + MAX_TAB_LENGTH);
+ }
+ this.tabLength = tabLength;
+ }
+
+ /**
+ * This filter reader redirects all read I/O methods through its own read()
+ * method.
+ *
+ * <P>
+ * The input stream is already buffered by the copy task so this doesn't
+ * significantly impact performance while it makes writing the individual
+ * fix filters much easier.
+ * </P>
+ */
+ private static class SimpleFilterReader extends Reader {
+ private static final int PREEMPT_BUFFER_LENGTH = 16;
+ private Reader in;
+
+ private int[] preempt = new int[PREEMPT_BUFFER_LENGTH];
+
+ private int preemptIndex = 0;
+
+ public SimpleFilterReader(Reader in) {
+ this.in = in;
+ }
+
+ public void push(char c) {
+ push((int) c);
+ }
+
+ public void push(int c) {
+ try {
+ preempt[preemptIndex++] = c;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ int[] p2 = new int[preempt.length * 2];
+ System.arraycopy(preempt, 0, p2, 0, preempt.length);
+ preempt = p2;
+ push(c);
+ }
+ }
+
+ public void push(char[] cs, int start, int length) {
+ for (int i = start + length - 1; i >= start;) {
+ push(cs[i--]);
+ }
+ }
+
+ public void push(char[] cs) {
+ push(cs, 0, cs.length);
+ }
+
+ /**
+ * Does this filter want to block edits on the last character returned
+ * by read()?
+ */
+ public boolean editsBlocked() {
+ return in instanceof SimpleFilterReader && ((SimpleFilterReader) in).editsBlocked();
+ }
+
+ public int read() throws java.io.IOException {
+ return preemptIndex > 0 ? preempt[--preemptIndex] : in.read();
+ }
+
+ public void close() throws java.io.IOException {
+ in.close();
+ }
+
+ public void reset() throws IOException {
+ in.reset();
+ }
+
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ public boolean ready() throws java.io.IOException {
+ return in.ready();
+ }
+
+ public void mark(int i) throws java.io.IOException {
+ in.mark(i);
+ }
+
+ public long skip(long i) throws java.io.IOException {
+ return in.skip(i);
+ }
+
+ public int read(char[] buf) throws java.io.IOException {
+ return read(buf, 0, buf.length);
+ }
+
+ public int read(char[] buf, int start, int length) throws java.io.IOException {
+ int count = 0;
+ int c = 0;
+
+ // CheckStyle:InnerAssignment OFF - leave alone
+ while (length-- > 0 && (c = this.read()) != -1) {
+ buf[start++] = (char) c;
+ count++;
+ }
+ // if at EOF with no characters in the buffer, return EOF
+ return (count == 0 && c == -1) ? -1 : count;
+ }
+ }
+
+ private static class MaskJavaTabLiteralsFilter extends SimpleFilterReader {
+ private boolean editsBlocked = false;
+
+ private static final int JAVA = 1;
+
+ private static final int IN_CHAR_CONST = 2;
+
+ private static final int IN_STR_CONST = 3;
+
+ private static final int IN_SINGLE_COMMENT = 4;
+
+ private static final int IN_MULTI_COMMENT = 5;
+
+ private static final int TRANS_TO_COMMENT = 6;
+
+ private static final int TRANS_FROM_MULTI = 8;
+
+ private int state;
+
+ public MaskJavaTabLiteralsFilter(Reader in) {
+ super(in);
+ state = JAVA;
+ }
+
+ public boolean editsBlocked() {
+ return editsBlocked || super.editsBlocked();
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+ // Mask, block from being edited, all characters in constants.
+ editsBlocked = (state == IN_CHAR_CONST || state == IN_STR_CONST);
+
+ switch (state) {
+ case JAVA:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '\'':
+ state = IN_CHAR_CONST;
+ break;
+ case '"':
+ state = IN_STR_CONST;
+ break;
+ case '/':
+ state = TRANS_TO_COMMENT;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_CHAR_CONST:
+ switch (thisChar) {
+ case '\'':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_STR_CONST:
+ switch (thisChar) {
+ case '"':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_SINGLE_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '\n':
+ case '\r': // EOL
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_MULTI_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '*':
+ state = TRANS_FROM_MULTI;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case TRANS_TO_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '*':
+ state = IN_MULTI_COMMENT;
+ break;
+ case '/':
+ state = IN_SINGLE_COMMENT;
+ break;
+ case '\'':
+ state = IN_CHAR_CONST;
+ break;
+ case '"':
+ state = IN_STR_CONST;
+ break;
+ default:
+ state = JAVA;
+ }
+ break;
+ case TRANS_FROM_MULTI:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '/':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ default:
+ // Fall tru
+ }
+ return thisChar;
+ }
+ }
+
+ private static class NormalizeEolFilter extends SimpleFilterReader {
+ private boolean previousWasEOL;
+
+ private boolean fixLast;
+
+ private int normalizedEOL = 0;
+
+ private char[] eol = null;
+
+ public NormalizeEolFilter(Reader in, String eolString, boolean fixLast) {
+ super(in);
+ eol = eolString.toCharArray();
+ this.fixLast = fixLast;
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+
+ if (normalizedEOL == 0) {
+ int numEOL = 0;
+ boolean atEnd = false;
+ switch (thisChar) {
+ case CTRLZ:
+ int c = super.read();
+ if (c == -1) {
+ atEnd = true;
+ if (fixLast && !previousWasEOL) {
+ numEOL = 1;
+ push(thisChar);
+ }
+ } else {
+ push(c);
+ }
+ break;
+ case -1:
+ atEnd = true;
+ if (fixLast && !previousWasEOL) {
+ numEOL = 1;
+ }
+ break;
+ case '\n':
+ // EOL was "\n"
+ numEOL = 1;
+ break;
+ case '\r':
+ numEOL = 1;
+ int c1 = super.read();
+ int c2 = super.read();
+
+ if (c1 == '\r' && c2 == '\n') {
+ // EOL was "\r\r\n"
+ } else if (c1 == '\r') {
+ // EOL was "\r\r" - handle as two consecutive "\r" and
+ // "\r"
+ numEOL = 2;
+ push(c2);
+ } else if (c1 == '\n') {
+ // EOL was "\r\n"
+ push(c2);
+ } else {
+ // EOL was "\r"
+ push(c2);
+ push(c1);
+ }
+ default:
+ // Fall tru
+ }
+ if (numEOL > 0) {
+ while (numEOL-- > 0) {
+ push(eol);
+ normalizedEOL += eol.length;
+ }
+ previousWasEOL = true;
+ thisChar = read();
+ } else if (!atEnd) {
+ previousWasEOL = false;
+ }
+ } else {
+ normalizedEOL--;
+ }
+ return thisChar;
+ }
+ }
+
+ private static class AddEofFilter extends SimpleFilterReader {
+ private int lastChar = -1;
+
+ public AddEofFilter(Reader in) {
+ super(in);
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+
+ // if source is EOF but last character was NOT ctrl-z, return ctrl-z
+ if (thisChar == -1) {
+ if (lastChar != CTRLZ) {
+ lastChar = CTRLZ;
+ return lastChar;
+ }
+ } else {
+ lastChar = thisChar;
+ }
+ return thisChar;
+ }
+ }
+
+ private static class RemoveEofFilter extends SimpleFilterReader {
+ private int lookAhead = -1;
+
+ public RemoveEofFilter(Reader in) {
+ super(in);
+
+ try {
+ lookAhead = in.read();
+ } catch (IOException e) {
+ lookAhead = -1;
+ }
+ }
+
+ public int read() throws IOException {
+ int lookAhead2 = super.read();
+
+ // If source at EOF and lookAhead is ctrl-z, return EOF (NOT ctrl-z)
+ if (lookAhead2 == -1 && lookAhead == CTRLZ) {
+ return -1;
+ }
+ // Return current look-ahead
+ int i = lookAhead;
+ lookAhead = lookAhead2;
+ return i;
+ }
+ }
+
+ private static class AddTabFilter extends SimpleFilterReader {
+ private int columnNumber = 0;
+
+ private int tabLength = 0;
+
+ public AddTabFilter(Reader in, int tabLength) {
+ super(in);
+ this.tabLength = tabLength;
+ }
+
+ public int read() throws IOException {
+ int c = super.read();
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ columnNumber = 0;
+ break;
+ case ' ':
+ columnNumber++;
+ if (!editsBlocked()) {
+ int colNextTab = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
+ int countSpaces = 1;
+ int numTabs = 0;
+
+ scanWhitespace: while ((c = super.read()) != -1) {
+ switch (c) {
+ case ' ':
+ if (++columnNumber == colNextTab) {
+ numTabs++;
+ countSpaces = 0;
+ colNextTab += tabLength;
+ } else {
+ countSpaces++;
+ }
+ break;
+ case '\t':
+ columnNumber = colNextTab;
+ numTabs++;
+ countSpaces = 0;
+ colNextTab += tabLength;
+ break;
+ default:
+ push(c);
+ break scanWhitespace;
+ }
+ }
+ while (countSpaces-- > 0) {
+ push(' ');
+ columnNumber--;
+ }
+ while (numTabs-- > 0) {
+ push('\t');
+ columnNumber -= tabLength;
+ }
+ c = super.read();
+ switch (c) {
+ case ' ':
+ columnNumber++;
+ break;
+ case '\t':
+ columnNumber += tabLength;
+ break;
+ default:
+ // Fall tru
+ }
+ }
+ break;
+ case '\t':
+ columnNumber = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
+ break;
+ default:
+ columnNumber++;
+ }
+ return c;
+ }
+ }
+
+ private static class RemoveTabFilter extends SimpleFilterReader {
+ private int columnNumber = 0;
+
+ private int tabLength = 0;
+
+ public RemoveTabFilter(Reader in, int tabLength) {
+ super(in);
+
+ this.tabLength = tabLength;
+ }
+
+ public int read() throws IOException {
+ int c = super.read();
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ columnNumber = 0;
+ break;
+ case '\t':
+ int width = tabLength - columnNumber % tabLength;
+
+ if (!editsBlocked()) {
+ for (; width > 1; width--) {
+ push(' ');
+ }
+ c = ' ';
+ }
+ columnNumber += width;
+ break;
+ default:
+ columnNumber++;
+ }
+ return c;
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "add" and "remove".
+ */
+ public static class AddAsisRemove extends EnumeratedAttribute {
+ private static final AddAsisRemove ASIS = newInstance("asis");
+
+ private static final AddAsisRemove ADD = newInstance("add");
+
+ private static final AddAsisRemove REMOVE = newInstance("remove");
+
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"add", "asis", "remove"};
+ }
+
+ /**
+ * Equality depending in the index.
+ * @param other the object to test equality against.
+ * @return true if the object has the same index as this.
+ */
+ public boolean equals(Object other) {
+ return other instanceof AddAsisRemove
+ && getIndex() == ((AddAsisRemove) other).getIndex();
+ }
+
+ /**
+ * Hashcode depending on the index.
+ * @return the index as the hashcode.
+ */
+ public int hashCode() {
+ return getIndex();
+ }
+
+ AddAsisRemove resolve() throws IllegalStateException {
+ if (this.equals(ASIS)) {
+ return ASIS;
+ }
+ if (this.equals(ADD)) {
+ return ADD;
+ }
+ if (this.equals(REMOVE)) {
+ return REMOVE;
+ }
+ throw new IllegalStateException("No replacement for " + this);
+ }
+
+ // Works like clone() but doesn't show up in the Javadocs
+ private AddAsisRemove newInstance() {
+ return newInstance(getValue());
+ }
+
+ /**
+ * Create an instance of this enumerated value based on the string value.
+ * @param value the value to use.
+ * @return an enumerated instance.
+ */
+ public static AddAsisRemove newInstance(String value) {
+ AddAsisRemove a = new AddAsisRemove();
+ a.setValue(value);
+ return a;
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
+ */
+ public static class CrLf extends EnumeratedAttribute {
+ private static final CrLf ASIS = newInstance("asis");
+
+ private static final CrLf CR = newInstance("cr");
+
+ private static final CrLf CRLF = newInstance("crlf");
+
+ private static final CrLf DOS = newInstance("dos");
+
+ private static final CrLf LF = newInstance("lf");
+
+ private static final CrLf MAC = newInstance("mac");
+
+ private static final CrLf UNIX = newInstance("unix");
+
+ /**
+ * @see EnumeratedAttribute#getValues
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"asis", "cr", "lf", "crlf", "mac", "unix", "dos"};
+ }
+
+ /**
+ * Equality depending in the index.
+ * @param other the object to test equality against.
+ * @return true if the object has the same index as this.
+ */
+ public boolean equals(Object other) {
+ return other instanceof CrLf && getIndex() == ((CrLf) other).getIndex();
+ }
+
+ /**
+ * Hashcode depending on the index.
+ * @return the index as the hashcode.
+ */
+ public int hashCode() {
+ return getIndex();
+ }
+
+ CrLf resolve() {
+ if (this.equals(ASIS)) {
+ return ASIS;
+ }
+ if (this.equals(CR) || this.equals(MAC)) {
+ return CR;
+ }
+ if (this.equals(CRLF) || this.equals(DOS)) {
+ return CRLF;
+ }
+ if (this.equals(LF) || this.equals(UNIX)) {
+ return LF;
+ }
+ throw new IllegalStateException("No replacement for " + this);
+ }
+
+ // Works like clone() but doesn't show up in the Javadocs
+ private CrLf newInstance() {
+ return newInstance(getValue());
+ }
+
+ /**
+ * Create an instance of this enumerated value based on the string value.
+ * @param value the value to use.
+ * @return an enumerated instance.
+ */
+ public static CrLf newInstance(String value) {
+ CrLf c = new CrLf();
+ c.setValue(value);
+ return c;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java
new file mode 100644
index 00000000..522fe57b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java
@@ -0,0 +1,222 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.util.LineTokenizer;
+
+/**
+ * Reads the first <code>n</code> lines of a stream.
+ * (Default is first 10 lines.)
+ * <p>
+ * Example:
+ * <pre>&lt;headfilter lines=&quot;3&quot;/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
+ * &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class HeadFilter extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the number of lines to be returned. */
+ private static final String LINES_KEY = "lines";
+
+ /** Parameter name for the number of lines to be skipped. */
+ private static final String SKIP_KEY = "skip";
+
+ /** Number of lines currently read in. */
+ private long linesRead = 0;
+
+ /** Default number of lines to show */
+ private static final int DEFAULT_NUM_LINES = 10;
+
+ /** Number of lines to be returned in the filtered stream. */
+ private long lines = DEFAULT_NUM_LINES;
+
+ /** Number of lines to be skipped. */
+ private long skip = 0;
+
+ /** A line tokenizer */
+ private LineTokenizer lineTokenizer = null;
+
+ /** the current line from the input stream */
+ private String line = null;
+ /** the position in the current line */
+ private int linePos = 0;
+
+ /** Whether this filter is finished */
+ private boolean eof;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public HeadFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public HeadFilter(final Reader in) {
+ super(in);
+ lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired
+ * number of lines have already been read, the resulting stream is
+ * effectively at an end. Otherwise, the next character from the
+ * underlying stream is read and returned.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ while (line == null || line.length() == 0) {
+ line = lineTokenizer.getToken(in);
+ if (line == null) {
+ return -1;
+ }
+ line = headFilter(line);
+ if (eof) {
+ return -1;
+ }
+ linePos = 0;
+ }
+
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param lines the number of lines to be returned in the filtered stream
+ */
+ public void setLines(final long lines) {
+ this.lines = lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return the number of lines to be returned in the filtered stream
+ */
+ private long getLines() {
+ return lines;
+ }
+
+ /**
+ * Sets the number of lines to be skipped in the filtered stream.
+ *
+ * @param skip the number of lines to be skipped in the filtered stream
+ */
+ public void setSkip(final long skip) {
+ this.skip = skip;
+ }
+
+ /**
+ * Returns the number of lines to be skipped in the filtered stream.
+ *
+ * @return the number of lines to be skipped in the filtered stream
+ */
+ private long getSkip() {
+ return skip;
+ }
+
+ /**
+ * Creates a new HeadFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ HeadFilter newFilter = new HeadFilter(rdr);
+ newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for skip parameter.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINES_KEY.equals(params[i].getName())) {
+ lines = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * implements a head filter on the input stream
+ */
+ private String headFilter(String line) {
+ linesRead++;
+ if (skip > 0) {
+ if ((linesRead - 1) < skip) {
+ return null;
+ }
+ }
+
+ if (lines > 0) {
+ if (linesRead > (lines + skip)) {
+ eof = true;
+ return null;
+ }
+ }
+ return line;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java
new file mode 100644
index 00000000..c83cae28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java
@@ -0,0 +1,244 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Filter which includes only those lines that contain all the user-specified
+ * strings.
+ *
+ * Example:
+ *
+ * <pre>&lt;linecontains&gt;
+ * &lt;contains value=&quot;foo&quot;&gt;
+ * &lt;contains value=&quot;bar&quot;&gt;
+ * &lt;/linecontains&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContains&quot;&gt;
+ * &lt;param type=&quot;contains&quot; value=&quot;foo&quot;/&gt;
+ * &lt;param type=&quot;contains&quot; value=&quot;bar&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * This will include only those lines that contain <code>foo</code> and
+ * <code>bar</code>.
+ *
+ */
+public final class LineContains
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the words to filter on. */
+ private static final String CONTAINS_KEY = "contains";
+
+ /** Parameter name for the words to filter on. */
+ private static final String NEGATE_KEY = "negate";
+
+ /** Vector that holds the strings that input lines must contain. */
+ private Vector<String> contains = new Vector<String>();
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if
+ * the next call to <code>read()</code> should read the original stream
+ * to find the next matching line.
+ */
+ private String line = null;
+
+ private boolean negate = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public LineContains() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public LineContains(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which contain all of the specified words.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ final int containsSize = contains.size();
+
+ for (line = readLine(); line != null; line = readLine()) {
+ boolean matches = true;
+ for (int i = 0; matches && i < containsSize; i++) {
+ String containsStr = (String) contains.elementAt(i);
+ matches = line.indexOf(containsStr) >= 0;
+ }
+ if (matches ^ isNegated()) {
+ break;
+ }
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Adds a <code>contains</code> element.
+ *
+ * @param contains The <code>contains</code> element to add.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredContains(final Contains contains) {
+ this.contains.addElement(contains.getValue());
+ }
+
+ /**
+ * Set the negation mode. Default false (no negation).
+ * @param b the boolean negation mode to set.
+ */
+ public void setNegate(boolean b) {
+ negate = b;
+ }
+
+ /**
+ * Find out whether we have been negated.
+ * @return boolean negation flag.
+ */
+ public boolean isNegated() {
+ return negate;
+ }
+
+ /**
+ * Sets the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @param contains A vector of words which must be contained within a line
+ * in order for it to match in this filter. Must not be <code>null</code>.
+ */
+ private void setContains(final Vector<String> contains) {
+ this.contains = contains;
+ }
+
+ /**
+ * Returns the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @return the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter. The
+ * returned object is "live" - in other words, changes made to the
+ * returned object are mirrored in the filter.
+ */
+ private Vector<String> getContains() {
+ return contains;
+ }
+
+ /**
+ * Creates a new LineContains using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ LineContains newFilter = new LineContains(rdr);
+ newFilter.setContains(getContains());
+ newFilter.setNegate(isNegated());
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to add user-defined contains strings.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (CONTAINS_KEY.equals(params[i].getType())) {
+ contains.addElement(params[i].getValue());
+ } else if (NEGATE_KEY.equals(params[i].getType())) {
+ setNegate(Project.toBoolean(params[i].getValue()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Holds a contains element
+ */
+ public static class Contains {
+
+ /** User defined contains string */
+ private String value;
+
+ /**
+ * Sets the contains string
+ *
+ * @param contains The contains string to set.
+ * Must not be <code>null</code>.
+ */
+ public final void setValue(String contains) {
+ value = contains;
+ }
+
+ /**
+ * Returns the contains string.
+ *
+ * @return the contains string for this element
+ */
+ public final String getValue() {
+ return value;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
new file mode 100644
index 00000000..23a2005d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
@@ -0,0 +1,242 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Filter which includes only those lines that contain the user-specified
+ * regular expression matching strings.
+ *
+ * Example:
+ * <pre>&lt;linecontainsregexp&gt;
+ * &lt;regexp pattern=&quot;foo*&quot;&gt;
+ * &lt;/linecontainsregexp&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContainsRegExp&quot;&gt;
+ * &lt;param type=&quot;regexp&quot; value=&quot;foo*&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * This will fetch all those lines that contain the pattern <code>foo</code>
+ *
+ */
+public final class LineContainsRegExp
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the regular expression to filter on. */
+ private static final String REGEXP_KEY = "regexp";
+
+ /** Parameter name for the negate attribute. */
+ private static final String NEGATE_KEY = "negate";
+
+ /** Parameter name for the casesensitive attribute. */
+ private static final String CS_KEY = "casesensitive";
+
+ /** Vector that holds the expressions that input lines must contain. */
+ private Vector<RegularExpression> regexps = new Vector<RegularExpression>();
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if
+ * the next call to <code>read()</code> should read the original stream
+ * to find the next matching line.
+ */
+ private String line = null;
+
+ private boolean negate = false;
+ private int regexpOptions = Regexp.MATCH_DEFAULT;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public LineContainsRegExp() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public LineContainsRegExp(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which match all of the specified
+ * regular expressions.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ final int regexpsSize = regexps.size();
+
+ for (line = readLine(); line != null; line = readLine()) {
+ boolean matches = true;
+ for (int i = 0; matches && i < regexpsSize; i++) {
+ RegularExpression regexp
+ = (RegularExpression) regexps.elementAt(i);
+ Regexp re = regexp.getRegexp(getProject());
+ matches = re.matches(line, regexpOptions);
+ }
+ if (matches ^ isNegated()) {
+ break;
+ }
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Adds a <code>regexp</code> element.
+ *
+ * @param regExp The <code>regexp</code> element to add.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredRegexp(final RegularExpression regExp) {
+ this.regexps.addElement(regExp);
+ }
+
+ /**
+ * Sets the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @param regexps A vector of regular expressions which must be contained
+ * within a line in order for it to match in this filter. Must not be
+ * <code>null</code>.
+ */
+ private void setRegexps(final Vector<RegularExpression> regexps) {
+ this.regexps = regexps;
+ }
+
+ /**
+ * Returns the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @return the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter. The returned object is "live" - in other words, changes made to
+ * the returned object are mirrored in the filter.
+ */
+ private Vector<RegularExpression> getRegexps() {
+ return regexps;
+ }
+
+ /**
+ * Creates a new LineContainsRegExp using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ LineContainsRegExp newFilter = new LineContainsRegExp(rdr);
+ newFilter.setRegexps(getRegexps());
+ newFilter.setNegate(isNegated());
+ newFilter
+ .setCaseSensitive(!RegexpUtil.hasFlag(regexpOptions,
+ Regexp.MATCH_CASE_INSENSITIVE)
+ );
+ return newFilter;
+ }
+
+ /**
+ * Set the negation mode. Default false (no negation).
+ * @param b the boolean negation mode to set.
+ */
+ public void setNegate(boolean b) {
+ negate = b;
+ }
+
+ /**
+ * Whether to match casesensitevly.
+ * @since Ant 1.8.2
+ */
+ public void setCaseSensitive(boolean b) {
+ regexpOptions = RegexpUtil.asOptions(b);
+ }
+
+ /**
+ * Find out whether we have been negated.
+ * @return boolean negation flag.
+ */
+ public boolean isNegated() {
+ return negate;
+ }
+
+ /**
+ * Parses parameters to add user defined regular expressions.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (REGEXP_KEY.equals(params[i].getType())) {
+ String pattern = params[i].getValue();
+ RegularExpression regexp = new RegularExpression();
+ regexp.setPattern(pattern);
+ regexps.addElement(regexp);
+ } else if (NEGATE_KEY.equals(params[i].getType())) {
+ setNegate(Project.toBoolean(params[i].getValue()));
+ } else if (CS_KEY.equals(params[i].getType())) {
+ setCaseSensitive(Project.toBoolean(params[i].getValue()));
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java
new file mode 100644
index 00000000..324397e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java
@@ -0,0 +1,164 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Attaches a prefix to every line.
+ *
+ * Example:
+ * <pre>&lt;prefixlines prefix=&quot;Foo&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.PrefixLines&quot;&gt;
+ * &lt;param name=&quot;prefix&quot; value=&quot;Foo&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class PrefixLines
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the prefix. */
+ private static final String PREFIX_KEY = "prefix";
+
+ /** The prefix to be used. */
+ private String prefix = null;
+
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public PrefixLines() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public PrefixLines(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. One line is read
+ * from the original input, and the prefix added. The resulting
+ * line is then used until it ends, at which point the next original line
+ * is read, etc.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ queuedData = readLine();
+ if (queuedData == null) {
+ ch = -1;
+ } else {
+ if (prefix != null) {
+ queuedData = prefix + queuedData;
+ }
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the prefix to add at the start of each input line.
+ *
+ * @param prefix The prefix to add at the start of each input line.
+ * May be <code>null</code>, in which case no prefix
+ * is added.
+ */
+ public void setPrefix(final String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Returns the prefix which will be added at the start of each input line.
+ *
+ * @return the prefix which will be added at the start of each input line
+ */
+ private String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Creates a new PrefixLines filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ PrefixLines newFilter = new PrefixLines(rdr);
+ newFilter.setPrefix(getPrefix());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes the prefix if it is available from the parameters.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (PREFIX_KEY.equals(params[i].getName())) {
+ prefix = params[i].getValue();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java
new file mode 100644
index 00000000..21ca3bc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java
@@ -0,0 +1,379 @@
+/*
+ * 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.filters;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Replaces tokens in the original input with user-supplied values.
+ *
+ * Example:
+ *
+ * <pre>&lt;replacetokens begintoken=&quot;#&quot; endtoken=&quot;#&quot;&gt;
+ * &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ * &lt;/replacetokens&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"&gt;
+ * &lt;param type="tokenchar" name="begintoken" value="#"/&gt;
+ * &lt;param type="tokenchar" name="endtoken" value="#"/&gt;
+ * &lt;param type="token" name="DATE" value="${TODAY}"/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class ReplaceTokens
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Default "begin token" character. */
+ private static final String DEFAULT_BEGIN_TOKEN = "@";
+
+ /** Default "end token" character. */
+ private static final String DEFAULT_END_TOKEN = "@";
+
+ /** Hashtable to holds the original replacee-replacer pairs (String to String). */
+ private Hashtable<String, String> hash = new Hashtable<String, String>();
+
+ /** This map holds the "resolved" tokens (begin- and end-tokens are added to make searching simpler) */
+ private final TreeMap<String, String> resolvedTokens = new TreeMap<String, String>();
+ private boolean resolvedTokensBuilt = false;
+ /** Used for comparisons and lookup into the resolvedTokens map. */
+ private String readBuffer = "";
+
+ /** replacement test from a token */
+ private String replaceData = null;
+
+ /** Index into replacement data */
+ private int replaceIndex = -1;
+
+ /** Character marking the beginning of a token. */
+ private String beginToken = DEFAULT_BEGIN_TOKEN;
+
+ /** Character marking the end of a token. */
+ private String endToken = DEFAULT_END_TOKEN;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ReplaceTokens() {}
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ReplaceTokens(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, replacing tokens
+ * from the original stream.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ if (!resolvedTokensBuilt) {
+ // build the resolved tokens tree map.
+ for (String key : hash.keySet()) {
+ resolvedTokens.put(beginToken + key + endToken, hash.get(key));
+ }
+ resolvedTokensBuilt = true;
+ }
+
+ // are we currently serving replace data?
+ if (replaceData != null) {
+ if (replaceIndex < replaceData.length()) {
+ return replaceData.charAt(replaceIndex++);
+ } else {
+ replaceData = null;
+ }
+ }
+
+ // is the read buffer empty?
+ if (readBuffer.length() == 0) {
+ int next = in.read();
+ if (next == -1) {
+ return next; // end of stream. all buffers empty.
+ }
+ readBuffer += (char)next;
+ }
+
+ for (;;) {
+ // get the closest tokens
+ SortedMap<String,String> possibleTokens = resolvedTokens.tailMap(readBuffer);
+ if (possibleTokens.isEmpty() || !possibleTokens.firstKey().startsWith(readBuffer)) { // if there is none, then deliver the first char from the buffer.
+ return getFirstCharacterFromReadBuffer();
+ } else if (readBuffer.equals(possibleTokens.firstKey())) { // there exists a nearest token - is it an exact match?
+ // we have found a token. prepare the replaceData buffer.
+ replaceData = resolvedTokens.get(readBuffer);
+ replaceIndex = 0;
+ readBuffer = ""; // destroy the readBuffer - it's contents are being replaced entirely.
+ // get the first character via recursive call.
+ return read();
+ } else { // nearest token is not matching exactly - read one character more.
+ int next = in.read();
+ if (next != -1) {
+ readBuffer += (char)next;
+ } else {
+ return getFirstCharacterFromReadBuffer(); // end of stream. deliver remaining characters from buffer.
+ }
+ }
+ }
+ }
+
+ /**
+ * @return the first character from the read buffer or -1 if read buffer is empty.
+ */
+ private int getFirstCharacterFromReadBuffer() {
+ if (readBuffer.length() > 0) {
+ int chr = readBuffer.charAt(0);
+ readBuffer = readBuffer.substring(1);
+ return chr;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Sets the "begin token" character.
+ *
+ * @param beginToken the character used to denote the beginning of a token
+ */
+ public void setBeginToken(final String beginToken) {
+ this.beginToken = beginToken;
+ }
+
+ /**
+ * Returns the "begin token" character.
+ *
+ * @return the character used to denote the beginning of a token
+ */
+ private String getBeginToken() {
+ return beginToken;
+ }
+
+ /**
+ * Sets the "end token" character.
+ *
+ * @param endToken the character used to denote the end of a token
+ */
+ public void setEndToken(final String endToken) {
+ this.endToken = endToken;
+ }
+
+ /**
+ * Returns the "end token" character.
+ *
+ * @return the character used to denote the end of a token
+ */
+ private String getEndToken() {
+ return endToken;
+ }
+
+ /**
+ * A resource containing properties, each of which is interpreted
+ * as a token/value pair.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPropertiesResource(Resource r) {
+ makeTokensFromProperties(r);
+ }
+
+ /**
+ * Adds a token element to the map of tokens to replace.
+ *
+ * @param token The token to add to the map of replacements.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredToken(final Token token) {
+ hash.put(token.getKey(), token.getValue());
+ resolvedTokensBuilt = false; // invalidate to build them again if they have been built already.
+ }
+
+ /**
+ * Returns properties from a specified properties file.
+ *
+ * @param resource The resource to load properties from.
+ */
+ private Properties getProperties(Resource resource) {
+ InputStream in = null;
+ Properties props = new Properties();
+ try {
+ in = resource.getInputStream();
+ props.load(in);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ FileUtils.close(in);
+ }
+
+ return props;
+ }
+
+ /**
+ * Sets the map of tokens to replace.
+ *
+ * @param hash A map (String->String) of token keys to replacement
+ * values. Must not be <code>null</code>.
+ */
+ private void setTokens(final Hashtable<String, String> hash) {
+ this.hash = hash;
+ }
+
+ /**
+ * Returns the map of tokens which will be replaced.
+ *
+ * @return a map (String->String) of token keys to replacement
+ * values
+ */
+ private Hashtable<String, String> getTokens() {
+ return hash;
+ }
+
+ /**
+ * Creates a new ReplaceTokens using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ReplaceTokens newFilter = new ReplaceTokens(rdr);
+ newFilter.setBeginToken(getBeginToken());
+ newFilter.setEndToken(getEndToken());
+ newFilter.setTokens(getTokens());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes tokens and loads the replacee-replacer hashtable.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (Parameter param : params) {
+ if (param != null) {
+ final String type = param.getType();
+ if ("tokenchar".equals(type)) {
+ final String name = param.getName();
+ if ("begintoken".equals(name)) {
+ beginToken = param.getValue();
+ } else if ("endtoken".equals(name)) {
+ endToken = param.getValue();
+ }
+ } else if ("token".equals(type)) {
+ final String name = param.getName();
+ final String value = param.getValue();
+ hash.put(name, value);
+ } else if ("propertiesfile".equals(type)) {
+ makeTokensFromProperties(
+ new FileResource(new File(param.getValue())));
+ }
+ }
+ }
+ }
+ }
+
+ private void makeTokensFromProperties(Resource r) {
+ Properties props = getProperties(r);
+ for (Enumeration<?> e = props.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = props.getProperty(key);
+ hash.put(key, value);
+ }
+ }
+
+ /**
+ * Holds a token
+ */
+ public static class Token {
+
+ /** Token key */
+ private String key;
+
+ /** Token value */
+ private String value;
+
+ /**
+ * Sets the token key
+ *
+ * @param key The key for this token. Must not be <code>null</code>.
+ */
+ public final void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * Sets the token value
+ *
+ * @param value The value for this token. Must not be <code>null</code>.
+ */
+ public final void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the key for this token.
+ *
+ * @return the key for this token
+ */
+ public final String getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the value for this token.
+ *
+ * @return the value for this token
+ */
+ public final String getValue() {
+ return value;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java
new file mode 100644
index 00000000..471660c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java
@@ -0,0 +1,375 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * <p>
+ * Sort a file before and/or after the file.
+ * </p>
+ *
+ * <p>
+ * Examples:
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location and copy
+ * them into <i>build</i> location. The lines of each file are sorted
+ * in ascendant order comparing the lines via the
+ * <code>String.compareTo(Object o)</code> method.
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter reverse=&quot;true&quot;/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location into reverse
+ * order and copy them into <i>build</i> location. If reverse parameter has
+ * value <code>true</code> (default value), then the output line of the files
+ * will be in ascendant order.
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.SortFilter&quot;&gt;
+ * &lt;param name=&quot;comparator&quot; value=&quot;org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ * &lt;/filterreader&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location using as
+ * sorting criterium <code>EvenFirstCmp</code> class, that sorts the file
+ * lines putting even lines first then odd lines for example. The modified files
+ * are copied into <i>build</i> location. The <code>EvenFirstCmp</code>,
+ * has to an instanciable class via <code>Class.newInstance()</code>,
+ * therefore in case of inner class has to be <em>static</em>. It also has to
+ * implement <code>java.util.Comparator</code> interface, for example:
+ * </p>
+ *
+ * <pre>
+ * package org.apache.tools.ant.filters;
+ * ...(omitted)
+ * public final class EvenFirstCmp implements &lt;b&gt;Comparator&lt;/b&gt; {
+ * public int compare(Object o1, Object o2) {
+ * ...(omitted)
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The example above is equivalent to:</p>
+ *
+ * <blockquote><pre>
+ * &lt;componentdef name="evenfirst"
+ * classname="org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter&gt;
+ * &lt;evenfirst/&gt;
+ * &lt;/sortfilter&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre></blockquote>
+ *
+ * <p> If parameter <code>comparator</code> is present, then
+ * <code>reverse</code> parameter will not be taken into account. </p>
+ *
+ * @since Ant 1.8.0
+ */
+public final class SortFilter extends BaseParamFilterReader
+ implements ChainableReader {
+
+ /** Parameter name for reverse order. */
+ private static final String REVERSE_KEY = "reverse";
+
+ /**
+ * Parameter name for specifying the comparator criteria via class that
+ * implement <code>java.util.Comparator</code> interface.
+ */
+ private static final String COMPARATOR_KEY = "comparator";
+
+ /**
+ * Instance of comparator class to be used for sorting.
+ */
+ private Comparator<? super String> comparator = null;
+
+ /**
+ * Controls if the sorting process will be in ascendant/descendant order. If
+ * If has value <code>true</code>, then the line of the file will be
+ * sorted on descendant order. Default value: <code>false</code>. It will
+ * be considered only if <code>comparator</code> is <code>null</code>.
+ */
+ private boolean reverse;
+
+ /**
+ * Stores the lines to be sorted.
+ */
+ private List<String> lines;
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if the
+ * next call to <code>read()</code> should read the original stream to
+ * find the next matching line.
+ */
+ private String line = null;
+
+ private Iterator<String> iterator = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public SortFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ */
+ public SortFilter(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired number
+ * of lines have already been read, the resulting stream is effectively at
+ * an end. Otherwise, the next character from the underlying stream is read
+ * and returned.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
+ * the resulting stream has been reached
+ *
+ * @exception IOException
+ * if the underlying stream throws an IOException during
+ * reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+ if (line != null) {
+ /*
+ * We are on the state: "reading the current line", lines are
+ * already sorted
+ */
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ if (lines == null) {
+ // We read all lines and sort them
+ lines = new ArrayList<String>();
+ for (line = readLine(); line != null; line = readLine()) {
+ lines.add(line);
+ }
+ sort();
+ iterator = lines.iterator();
+ }
+
+ if (iterator.hasNext()) {
+ line = (String) iterator.next();
+ } else {
+ line = null;
+ lines = null;
+ iterator = null;
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new SortReader using the passed in Reader for instantiation.
+ *
+ * @param rdr
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering the
+ * specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ SortFilter newFilter = new SortFilter(rdr);
+ newFilter.setReverse(isReverse());
+ newFilter.setComparator(getComparator());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Returns <code>true</code> if the sorting process will be in reverse
+ * order, otherwise the sorting process will be in ascendant order.
+ *
+ * @return <code>true</code> if the sorting process will be in reverse
+ * order, otherwise the sorting process will be in ascendant order.
+ */
+ public boolean isReverse() {
+ return reverse;
+ }
+
+ /**
+ * Sets the sorting process will be in ascendant (<code>reverse=false</code>)
+ * or to descendant (<code>reverse=true</code>).
+ *
+ * @param reverse
+ * Boolean representing reverse ordering process.
+ */
+ public void setReverse(boolean reverse) {
+ this.reverse = reverse;
+ }
+
+ /**
+ * Returns the comparator to be used for sorting.
+ *
+ * @return the comparator
+ */
+ public Comparator<? super String> getComparator() {
+ return comparator;
+ }
+
+ /**
+ * Set the comparator to be used as sorting criterium.
+ *
+ * @param comparator
+ * the comparator to set
+ */
+ public void setComparator(Comparator<? super String> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Set the comparator to be used as sorting criterion as nested element.
+ *
+ * @param comparator
+ * the comparator to set
+ */
+ public void add(Comparator<? super String> comparator) {
+ if (this.comparator != null && comparator != null) {
+ throw new BuildException("can't have more than one comparator");
+ }
+ setComparator(comparator);
+ }
+
+ /**
+ * Scans the parameters list
+ */
+ private void initialize() throws IOException {
+ // get parameters
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ final String paramName = params[i].getName();
+ if (REVERSE_KEY.equals(paramName)) {
+ setReverse(Boolean.valueOf(params[i].getValue())
+ .booleanValue());
+ continue;
+ }
+ if (COMPARATOR_KEY.equals(paramName)) {
+ try {
+ String className = (String) params[i].getValue();
+ @SuppressWarnings("unchecked")
+ final Comparator<? super String> comparatorInstance = (Comparator<? super String>) (Class
+ .forName(className).newInstance());
+ setComparator(comparatorInstance);
+ continue;
+ } catch (InstantiationException e) {
+ throw new BuildException(e);
+ } catch (IllegalAccessException e) {
+ /*
+ * Probably a inner non-static class, this this case is
+ * not considered
+ */
+ throw new BuildException(e);
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(e);
+ } catch (ClassCastException e) {
+ throw new BuildException("Value of comparator attribute"
+ + " should implement"
+ + " java.util.Comparator"
+ + " interface");
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sorts the read lines (<code>lines</code>) according to the sorting
+ * criteria defined by the user.
+ *
+ */
+ private void sort() {
+ if (comparator == null) {
+ if (reverse) {
+ Collections.sort(lines, new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return (-s1.compareTo(s2));
+ }
+ });
+ } else {
+ Collections.sort(lines);
+ }
+ } else {
+ Collections.sort(lines, comparator);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java
new file mode 100644
index 00000000..e150e965
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java
@@ -0,0 +1,49 @@
+/*
+ * 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.filters;
+
+import java.io.StringReader;
+
+import org.apache.tools.ant.util.ReaderInputStream;
+
+/**
+ * Wraps a String as an InputStream.
+ *
+ */
+public class StringInputStream extends ReaderInputStream {
+
+ /**
+ * Composes a stream from a String
+ *
+ * @param source The string to read from. Must not be <code>null</code>.
+ */
+ public StringInputStream(String source) {
+ super(new StringReader(source));
+ }
+
+ /**
+ * Composes a stream from a String with the specified encoding
+ *
+ * @param source The string to read from. Must not be <code>null</code>.
+ * @param encoding The encoding scheme. Also must not be <code>null</code>.
+ */
+ public StringInputStream(String source, String encoding) {
+ super(new StringReader(source), encoding);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java
new file mode 100644
index 00000000..65bccd70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java
@@ -0,0 +1,145 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This is a Java comment and string stripper reader that filters
+ * those lexical tokens out for purposes of simple Java parsing.
+ * (if you have more complex Java parsing needs, use a real lexer).
+ * Since this class heavily relies on the single char read function,
+ * you are recommended to make it work on top of a buffered reader.
+ *
+ */
+public final class StripJavaComments
+ extends BaseFilterReader
+ implements ChainableReader {
+
+ /**
+ * The read-ahead character, used for effectively pushing a single
+ * character back. A value of -1 indicates that no character is in the
+ * buffer.
+ */
+ private int readAheadCh = -1;
+
+ /**
+ * Whether or not the parser is currently in the middle of a string
+ * literal.
+ */
+ private boolean inString = false;
+
+ /**
+ * Whether or not the last char has been a backslash.
+ */
+ private boolean quoted = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripJavaComments() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripJavaComments(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, not including
+ * Java comments.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ int ch = -1;
+ if (readAheadCh != -1) {
+ ch = readAheadCh;
+ readAheadCh = -1;
+ } else {
+ ch = in.read();
+ if (ch == '"' && !quoted) {
+ inString = !inString;
+ quoted = false;
+ } else if (ch == '\\') {
+ quoted = !quoted;
+ } else {
+ quoted = false;
+ if (!inString) {
+ if (ch == '/') {
+ ch = in.read();
+ if (ch == '/') {
+ while (ch != '\n' && ch != -1 && ch != '\r') {
+ ch = in.read();
+ }
+ } else if (ch == '*') {
+ while (ch != -1) {
+ ch = in.read();
+ if (ch == '*') {
+ ch = in.read();
+ while (ch == '*') {
+ ch = in.read();
+ }
+
+ if (ch == '/') {
+ ch = read();
+ break;
+ }
+ }
+ }
+ } else {
+ readAheadCh = ch;
+ ch = '/';
+ }
+ }
+ }
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Creates a new StripJavaComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+
+ public Reader chain(final Reader rdr) {
+ StripJavaComments newFilter = new StripJavaComments(rdr);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java
new file mode 100644
index 00000000..9a97940a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java
@@ -0,0 +1,154 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Filter to flatten the stream to a single line.
+ *
+ * Example:
+ *
+ * <pre>&lt;striplinebreaks/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.StripLineBreaks&quot;/&gt;</pre>
+ *
+ */
+public final class StripLineBreaks
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /**
+ * Line-breaking characters.
+ * What should we do on funny IBM mainframes with odd line endings?
+ */
+ private static final String DEFAULT_LINE_BREAKS = "\r\n";
+
+ /** Parameter name for the line-breaking characters parameter. */
+ private static final String LINE_BREAKS_KEY = "linebreaks";
+
+ /** The characters that are recognized as line breaks. */
+ private String lineBreaks = DEFAULT_LINE_BREAKS;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripLineBreaks() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripLineBreaks(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * characters not in the set of line-breaking characters.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = in.read();
+ while (ch != -1) {
+ if (lineBreaks.indexOf(ch) == -1) {
+ break;
+ } else {
+ ch = in.read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the line-breaking characters.
+ *
+ * @param lineBreaks A String containing all the characters to be
+ * considered as line-breaking.
+ */
+ public void setLineBreaks(final String lineBreaks) {
+ this.lineBreaks = lineBreaks;
+ }
+
+ /**
+ * Returns the line-breaking characters as a String.
+ *
+ * @return a String containing all the characters considered as
+ * line-breaking
+ */
+ private String getLineBreaks() {
+ return lineBreaks;
+ }
+
+ /**
+ * Creates a new StripLineBreaks using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ StripLineBreaks newFilter = new StripLineBreaks(rdr);
+ newFilter.setLineBreaks(getLineBreaks());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the line-breaking characters.
+ */
+ private void initialize() {
+ String userDefinedLineBreaks = null;
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINE_BREAKS_KEY.equals(params[i].getName())) {
+ userDefinedLineBreaks = params[i].getValue();
+ break;
+ }
+ }
+ }
+ if (userDefinedLineBreaks != null) {
+ lineBreaks = userDefinedLineBreaks;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java
new file mode 100644
index 00000000..e3d240ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java
@@ -0,0 +1,237 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * This filter strips line comments.
+ *
+ * Example:
+ *
+ * <pre>&lt;striplinecomments&gt;
+ * &lt;comment value=&quot;#&quot;/&gt;
+ * &lt;comment value=&quot;--&quot;/&gt;
+ * &lt;comment value=&quot;REM &quot;/&gt;
+ * &lt;comment value=&quot;rem &quot;/&gt;
+ * &lt;comment value=&quot;//&quot;/&gt;
+ * &lt;/striplinecomments&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.StripLineComments&quot;&gt;
+ * &lt;param type=&quot;comment&quot; value="#&quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;--&quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;REM &quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;rem &quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;//&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class StripLineComments
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the comment prefix. */
+ private static final String COMMENTS_KEY = "comment";
+
+ /** Vector that holds the comment prefixes. */
+ private Vector<String> comments = new Vector<String>();
+
+ /** The line that has been read ahead. */
+ private String line = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripLineComments() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripLineComments(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which don't start with any of the
+ * specified comment prefixes.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ line = readLine();
+ final int commentsSize = comments.size();
+
+ while (line != null) {
+ for (int i = 0; i < commentsSize; i++) {
+ String comment = comments.elementAt(i);
+ if (line.startsWith(comment)) {
+ line = null;
+ break;
+ }
+ }
+
+ if (line == null) {
+ // line started with comment
+ line = readLine();
+ } else {
+ break;
+ }
+ }
+
+ if (line != null) {
+ return read();
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Adds a <code>comment</code> element to the list of prefixes.
+ *
+ * @param comment The <code>comment</code> element to add to the
+ * list of comment prefixes to strip. Must not be <code>null</code>.
+ */
+ public void addConfiguredComment(final Comment comment) {
+ comments.addElement(comment.getValue());
+ }
+
+ /**
+ * Sets the list of comment prefixes to strip.
+ *
+ * @param comments A list of strings, each of which is a prefix
+ * for a comment line. Must not be <code>null</code>.
+ */
+ private void setComments(final Vector<String> comments) {
+ this.comments = comments;
+ }
+
+ /**
+ * Returns the list of comment prefixes to strip.
+ *
+ * @return the list of comment prefixes to strip.
+ */
+ private Vector<String> getComments() {
+ return comments;
+ }
+
+ /**
+ * Creates a new StripLineComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ StripLineComments newFilter = new StripLineComments(rdr);
+ newFilter.setComments(getComments());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the comment prefixes.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (COMMENTS_KEY.equals(params[i].getType())) {
+ comments.addElement(params[i].getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * The class that holds a comment representation.
+ */
+ public static class Comment {
+
+ /** The prefix for a line comment. */
+ private String value;
+
+ /**
+ * Sets the prefix for this type of line comment.
+ *
+ * @param comment The prefix for a line comment of this type.
+ * Must not be <code>null</code>.
+ */
+ public final void setValue(String comment) {
+ if (value != null) {
+ throw new IllegalStateException("Comment value already set.");
+ }
+ value = comment;
+ }
+
+ /**
+ * Returns the prefix for this type of line comment.
+ *
+ * @return the prefix for this type of line comment.
+ */
+ public final String getValue() {
+ return value;
+ }
+
+ /**
+ * Alt. syntax to set the prefix for this type of line comment.
+ *
+ * @param comment The prefix for a line comment of this type.
+ * Must not be <code>null</code>.
+ */
+ public void addText(String comment) {
+ setValue(comment);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java
new file mode 100644
index 00000000..23d9b534
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java
@@ -0,0 +1,174 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Attaches a suffix to every line.
+ *
+ * Example:
+ * <pre>&lt;suffixlines suffix=&quot;Foo&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.SuffixLines&quot;&gt;
+ * &lt;param name=&quot;suffix&quot; value=&quot;Foo&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * @since Ant 1.8.0
+ */
+public final class SuffixLines
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the prefix. */
+ private static final String SUFFIX_KEY = "suffix";
+
+ /** The suffix to be used. */
+ private String suffix = null;
+
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public SuffixLines() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public SuffixLines(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. One line is read
+ * from the original input, and the suffix added. The resulting
+ * line is then used until it ends, at which point the next original line
+ * is read, etc.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ queuedData = readLine();
+ if (queuedData == null) {
+ ch = -1;
+ } else {
+ if (suffix != null) {
+ String lf = "";
+ if (queuedData.endsWith("\r\n")) {
+ lf = "\r\n";
+ } else if (queuedData.endsWith("\n")) {
+ lf = "\n";
+ }
+ queuedData =
+ queuedData.substring(0,
+ queuedData.length() - lf.length())
+ + suffix + lf;
+ }
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the suffix to add at the end of each input line.
+ *
+ * @param suffix The suffix to add at the end of each input line.
+ * May be <code>null</code>, in which case no suffix
+ * is added.
+ */
+ public void setSuffix(final String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * Returns the suffix which will be added at the end of each input line.
+ *
+ * @return the suffix which will be added at the end of each input line
+ */
+ private String getSuffix() {
+ return suffix;
+ }
+
+ /**
+ * Creates a new SuffixLines filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ SuffixLines newFilter = new SuffixLines(rdr);
+ newFilter.setSuffix(getSuffix());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes the suffix if it is available from the parameters.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (SUFFIX_KEY.equals(params[i].getName())) {
+ suffix = params[i].getValue();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java
new file mode 100644
index 00000000..adaaa7af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java
@@ -0,0 +1,155 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Converts tabs to spaces.
+ *
+ * Example:
+ *
+ * <pre>&lt;tabstospaces tablength=&quot;8&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.TabsToSpaces&quot;&gt;
+ * &lt;param name=&quot;tablength&quot; value=&quot;8&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class TabsToSpaces
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** The default tab length. */
+ private static final int DEFAULT_TAB_LENGTH = 8;
+
+ /** Parameter name for the length of a tab. */
+ private static final String TAB_LENGTH_KEY = "tablength";
+
+ /** Tab length in this filter. */
+ private int tabLength = DEFAULT_TAB_LENGTH;
+
+ /** The number of spaces still to be read to represent the last-read tab. */
+ private int spacesRemaining = 0;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TabsToSpaces() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TabsToSpaces(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, converting tabs
+ * to the specified number of spaces.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (spacesRemaining > 0) {
+ spacesRemaining--;
+ ch = ' ';
+ } else {
+ ch = in.read();
+ if (ch == '\t') {
+ spacesRemaining = tabLength - 1;
+ ch = ' ';
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the tab length.
+ *
+ * @param tabLength the number of spaces to be used when converting a tab.
+ */
+ public void setTablength(final int tabLength) {
+ this.tabLength = tabLength;
+ }
+
+ /**
+ * Returns the tab length.
+ *
+ * @return the number of spaces used when converting a tab
+ */
+ private int getTablength() {
+ return tabLength;
+ }
+
+ /**
+ * Creates a new TabsToSpaces using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ TabsToSpaces newFilter = new TabsToSpaces(rdr);
+ newFilter.setTablength(getTablength());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the tab length.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] != null) {
+ if (TAB_LENGTH_KEY.equals(params[i].getName())) {
+ tabLength = Integer.parseInt(params[i].getValue());
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java
new file mode 100644
index 00000000..fcc84d16
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java
@@ -0,0 +1,243 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.LinkedList;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.util.LineTokenizer;
+
+/**
+ * Reads the last <code>n</code> lines of a stream. (Default is last10 lines.)
+ *
+ * Example:
+ *
+ * <pre>&lt;tailfilter lines=&quot;3&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
+ * &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class TailFilter extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the number of lines to be returned. */
+ private static final String LINES_KEY = "lines";
+
+ /** Parameter name for the number of lines to be skipped. */
+ private static final String SKIP_KEY = "skip";
+
+ /** Default number of lines to show */
+ private static final int DEFAULT_NUM_LINES = 10;
+
+ /** Number of lines to be returned in the filtered stream. */
+ private long lines = DEFAULT_NUM_LINES;
+
+ /** Number of lines to be skipped. */
+ private long skip = 0;
+
+ /** Whether or not read-ahead been completed. */
+ private boolean completedReadAhead = false;
+
+ /** A line tokenizer */
+ private LineTokenizer lineTokenizer = null;
+
+ /** the current line from the input stream */
+ private String line = null;
+ /** the position in the current line */
+ private int linePos = 0;
+
+ private LinkedList<String> lineList = new LinkedList<String>();
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TailFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TailFilter(final Reader in) {
+ super(in);
+ lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the read-ahead
+ * has been completed, the next character in the buffer is returned.
+ * Otherwise, the stream is read to the end and buffered (with the buffer
+ * growing as necessary), then the appropriate position in the buffer is
+ * set to read from.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ while (line == null || line.length() == 0) {
+ line = lineTokenizer.getToken(in);
+ line = tailFilter(line);
+ if (line == null) {
+ return -1;
+ }
+ linePos = 0;
+ }
+
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param lines the number of lines to be returned in the filtered stream
+ */
+ public void setLines(final long lines) {
+ this.lines = lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return the number of lines to be returned in the filtered stream
+ */
+ private long getLines() {
+ return lines;
+ }
+
+ /**
+ * Sets the number of lines to be skipped in the filtered stream.
+ *
+ * @param skip the number of lines to be skipped in the filtered stream
+ */
+ public void setSkip(final long skip) {
+ this.skip = skip;
+ }
+
+ /**
+ * Returns the number of lines to be skipped in the filtered stream.
+ *
+ * @return the number of lines to be skipped in the filtered stream
+ */
+ private long getSkip() {
+ return skip;
+ }
+
+ /**
+ * Creates a new TailFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ TailFilter newFilter = new TailFilter(rdr);
+ newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for "skip" parameter.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINES_KEY.equals(params[i].getName())) {
+ setLines(Long.parseLong(params[i].getValue()));
+ continue;
+ }
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * implement a tail filter on a stream of lines.
+ * line = null is the end of the stream.
+ * @return "" while reading in the lines,
+ * line while outputting the lines
+ * null at the end of outputting the lines
+ */
+ private String tailFilter(String line) {
+ if (!completedReadAhead) {
+ if (line != null) {
+ lineList.add(line);
+ if (lines == -1) {
+ if (lineList.size() > skip) {
+ return lineList.removeFirst();
+ }
+ } else {
+ long linesToKeep = lines + (skip > 0 ? skip : 0);
+ if (linesToKeep < lineList.size()) {
+ lineList.removeFirst();
+ }
+ }
+ return "";
+ }
+ completedReadAhead = true;
+ if (skip > 0) {
+ for (int i = 0; i < skip; ++i) {
+ lineList.removeLast();
+ }
+ }
+ if (lines > -1) {
+ while (lineList.size() > lines) {
+ lineList.removeFirst();
+ }
+ }
+ }
+ if (lineList.size() > 0) {
+ return lineList.removeFirst();
+ }
+ return null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java
new file mode 100644
index 00000000..ebad7602
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java
@@ -0,0 +1,712 @@
+/*
+ * 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.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.types.Substitution;
+import org.apache.tools.ant.util.LineTokenizer;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.Tokenizer;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * This splits up input into tokens and passes
+ * the tokens to a sequence of filters.
+ *
+ * @since Ant 1.6
+ * @see BaseFilterReader
+ * @see ChainableReader
+ * @see org.apache.tools.ant.DynamicConfigurator
+ */
+public class TokenFilter extends BaseFilterReader
+ implements ChainableReader {
+ /**
+ * string filters implement this interface
+ */
+ public interface Filter {
+ /**
+ * filter and/of modify a string
+ *
+ * @param string the string to filter
+ * @return the modified string or null if the
+ * string did not pass the filter
+ */
+ String filter(String string);
+ }
+
+
+ /** string filters */
+ private Vector<Filter> filters = new Vector<Filter>();
+ /** the tokenizer to use on the input stream */
+ private Tokenizer tokenizer = null;
+ /** the output token termination */
+ private String delimOutput = null;
+ /** the current string token from the input stream */
+ private String line = null;
+ /** the position in the current string token */
+ private int linePos = 0;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TokenFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TokenFilter(final Reader in) {
+ super(in);
+ }
+
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which match all of the specified
+ * regular expressions.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+
+ public int read() throws IOException {
+ if (tokenizer == null) {
+ tokenizer = new LineTokenizer();
+ }
+ while (line == null || line.length() == 0) {
+ line = tokenizer.getToken(in);
+ if (line == null) {
+ return -1;
+ }
+ for (Enumeration<Filter> e = filters.elements(); e.hasMoreElements();) {
+ Filter filter = e.nextElement();
+ line = filter.filter(line);
+ if (line == null) {
+ break;
+ }
+ }
+ linePos = 0;
+ if (line != null) {
+ if (tokenizer.getPostToken().length() != 0) {
+ if (delimOutput != null) {
+ line = line + delimOutput;
+ } else {
+ line = line + tokenizer.getPostToken();
+ }
+ }
+ }
+ }
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new TokenFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param reader A Reader object providing the underlying stream.
+ *
+ * @return a new filter based on this configuration
+ */
+
+ public final Reader chain(final Reader reader) {
+ TokenFilter newFilter = new TokenFilter(reader);
+ newFilter.filters = filters;
+ newFilter.tokenizer = tokenizer;
+ newFilter.delimOutput = delimOutput;
+ newFilter.setProject(getProject());
+ return newFilter;
+ }
+
+ /**
+ * set the output delimiter.
+ * @param delimOutput replaces the delim string returned by the
+ * tokenizer, if present.
+ */
+
+ public void setDelimOutput(String delimOutput) {
+ this.delimOutput = resolveBackSlash(delimOutput);
+ }
+
+ // -----------------------------------------
+ // Predefined tokenizers
+ // -----------------------------------------
+
+ /**
+ * add a line tokenizer - this is the default.
+ * @param tokenizer the line tokenizer
+ */
+
+ public void addLineTokenizer(LineTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add a string tokenizer
+ * @param tokenizer the string tokenizer
+ */
+
+ public void addStringTokenizer(StringTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add a file tokenizer
+ * @param tokenizer the file tokenizer
+ */
+ public void addFileTokenizer(FileTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add an arbitrary tokenizer
+ * @param tokenizer the tokenizer to all, only one allowed
+ */
+
+ public void add(Tokenizer tokenizer) {
+ if (this.tokenizer != null) {
+ throw new BuildException("Only one tokenizer allowed");
+ }
+ this.tokenizer = tokenizer;
+ }
+
+ // -----------------------------------------
+ // Predefined filters
+ // -----------------------------------------
+
+ /**
+ * replace string filter
+ * @param filter the replace string filter
+ */
+ public void addReplaceString(ReplaceString filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * contains string filter
+ * @param filter the contains string filter
+ */
+ public void addContainsString(ContainsString filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * replace regex filter
+ * @param filter the replace regex filter
+ */
+ public void addReplaceRegex(ReplaceRegex filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * contains regex filter
+ * @param filter the contains regex filter
+ */
+ public void addContainsRegex(ContainsRegex filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * trim filter
+ * @param filter the trim filter
+ */
+ public void addTrim(Trim filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * ignore blank filter
+ * @param filter the ignore blank filter
+ */
+ public void addIgnoreBlank(IgnoreBlank filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * delete chars
+ * @param filter the delete characters filter
+ */
+ public void addDeleteCharacters(DeleteCharacters filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * Add an arbitrary filter
+ * @param filter the filter to add
+ */
+ public void add(Filter filter) {
+ filters.addElement(filter);
+ }
+
+
+ // --------------------------------------------
+ //
+ // Tokenizer Classes (impls moved to oata.util)
+ //
+ // --------------------------------------------
+
+ /**
+ * class to read the complete input into a string
+ */
+ public static class FileTokenizer
+ extends org.apache.tools.ant.util.FileTokenizer {
+ }
+
+ /**
+ * class to tokenize the input as areas separated
+ * by white space, or by a specified list of
+ * delim characters. Behaves like java.util.StringTokenizer.
+ * if the stream starts with delim characters, the first
+ * token will be an empty string (unless the treat delims
+ * as tokens flag is set).
+ */
+ public static class StringTokenizer
+ extends org.apache.tools.ant.util.StringTokenizer {
+ }
+
+ // --------------------------------------------
+ //
+ // Filter classes
+ //
+ // --------------------------------------------
+
+ /**
+ * Abstract class that converts derived filter classes into
+ * ChainableReaderFilter's
+ */
+ public abstract static class ChainableReaderFilter extends ProjectComponent
+ implements ChainableReader, Filter {
+ private boolean byLine = true;
+
+ /**
+ * set whether to use filetokenizer or line tokenizer
+ * @param byLine if true use a linetokenizer (default) otherwise
+ * use a filetokenizer
+ */
+ public void setByLine(boolean byLine) {
+ this.byLine = byLine;
+ }
+
+ /**
+ * Chain a tokenfilter reader to a reader,
+ *
+ * @param reader the input reader object
+ * @return the chained reader object
+ */
+ public Reader chain(Reader reader) {
+ TokenFilter tokenFilter = new TokenFilter(reader);
+ if (!byLine) {
+ tokenFilter.add(new FileTokenizer());
+ }
+ tokenFilter.add(this);
+ return tokenFilter;
+ }
+ }
+
+ /**
+ * Simple replace string filter.
+ */
+ public static class ReplaceString extends ChainableReaderFilter {
+ private String from;
+ private String to;
+
+ /**
+ * the from attribute
+ *
+ * @param from the string to replace
+ */
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ /**
+ * the to attribute
+ *
+ * @param to the string to replace 'from' with
+ */
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ /**
+ * Filter a string 'line' replacing from with to
+ * (Copy&amp;Paste from the Replace task)
+ * @param line the string to be filtered
+ * @return the filtered line
+ */
+ public String filter(String line) {
+ if (from == null) {
+ throw new BuildException("Missing from in stringreplace");
+ }
+ StringBuffer ret = new StringBuffer();
+ int start = 0;
+ int found = line.indexOf(from);
+ while (found >= 0) {
+ // write everything up to the from
+ if (found > start) {
+ ret.append(line.substring(start, found));
+ }
+
+ // write the replacement to
+ if (to != null) {
+ ret.append(to);
+ }
+
+ // search again
+ start = found + from.length();
+ found = line.indexOf(from, start);
+ }
+
+ // write the remaining characters
+ if (line.length() > start) {
+ ret.append(line.substring(start, line.length()));
+ }
+
+ return ret.toString();
+ }
+ }
+
+ /**
+ * Simple filter to filter lines contains strings
+ */
+ public static class ContainsString extends ProjectComponent
+ implements Filter {
+ private String contains;
+
+ /**
+ * the contains attribute
+ * @param contains the string that the token should contain
+ */
+ public void setContains(String contains) {
+ this.contains = contains;
+ }
+
+ /**
+ * Filter strings that contain the contains attribute
+ *
+ * @param string the string to be filtered
+ * @return null if the string does not contain "contains",
+ * string otherwise
+ */
+ public String filter(String string) {
+ if (contains == null) {
+ throw new BuildException("Missing contains in containsstring");
+ }
+ if (string.indexOf(contains) > -1) {
+ return string;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * filter to replace regex.
+ */
+ public static class ReplaceRegex extends ChainableReaderFilter {
+ private String from;
+ private String to;
+ private RegularExpression regularExpression;
+ private Substitution substitution;
+ private boolean initialized = false;
+ private String flags = "";
+ private int options;
+ private Regexp regexp;
+
+ /**
+ * the from attribute
+ * @param from the regex string
+ */
+ public void setPattern(String from) {
+ this.from = from;
+ }
+ /**
+ * the to attribute
+ * @param to the replacement string
+ */
+ public void setReplace(String to) {
+ this.to = to;
+ }
+
+ /**
+ * @param flags the regex flags
+ */
+ public void setFlags(String flags) {
+ this.flags = flags;
+ }
+
+ private void initialize() {
+ if (initialized) {
+ return;
+ }
+ options = convertRegexOptions(flags);
+ if (from == null) {
+ throw new BuildException("Missing pattern in replaceregex");
+ }
+ regularExpression = new RegularExpression();
+ regularExpression.setPattern(from);
+ regexp = regularExpression.getRegexp(getProject());
+ if (to == null) {
+ to = "";
+ }
+ substitution = new Substitution();
+ substitution.setExpression(to);
+ }
+
+ /**
+ * @param line the string to modify
+ * @return the modified string
+ */
+ public String filter(String line) {
+ initialize();
+
+ if (!regexp.matches(line, options)) {
+ return line;
+ }
+ return regexp.substitute(
+ line, substitution.getExpression(getProject()), options);
+ }
+ }
+
+ /**
+ * filter to filter tokens matching regular expressions.
+ */
+ public static class ContainsRegex extends ChainableReaderFilter {
+ private String from;
+ private String to;
+ private RegularExpression regularExpression;
+ private Substitution substitution;
+ private boolean initialized = false;
+ private String flags = "";
+ private int options;
+ private Regexp regexp;
+
+
+ /**
+ * @param from the regex pattern
+ */
+ public void setPattern(String from) {
+ this.from = from;
+ }
+
+ /**
+ * @param to the replacement string
+ */
+ public void setReplace(String to) {
+ this.to = to;
+ }
+
+ /**
+ * @param flags the regex flags
+ */
+ public void setFlags(String flags) {
+ this.flags = flags;
+ }
+
+ private void initialize() {
+ if (initialized) {
+ return;
+ }
+ options = convertRegexOptions(flags);
+ if (from == null) {
+ throw new BuildException("Missing from in containsregex");
+ }
+ regularExpression = new RegularExpression();
+ regularExpression.setPattern(from);
+ regexp = regularExpression.getRegexp(getProject());
+ if (to == null) {
+ return;
+ }
+ substitution = new Substitution();
+ substitution.setExpression(to);
+ }
+
+ /**
+ * apply regex and substitution on a string
+ * @param string the string to apply filter on
+ * @return the filtered string
+ */
+ public String filter(String string) {
+ initialize();
+ if (!regexp.matches(string, options)) {
+ return null;
+ }
+ if (substitution == null) {
+ return string;
+ }
+ return regexp.substitute(
+ string, substitution.getExpression(getProject()), options);
+ }
+ }
+
+ /** Filter to trim white space */
+ public static class Trim extends ChainableReaderFilter {
+ /**
+ * @param line the string to be trimmed
+ * @return the trimmed string
+ */
+ public String filter(String line) {
+ return line.trim();
+ }
+ }
+
+
+
+ /** Filter remove empty tokens */
+ public static class IgnoreBlank extends ChainableReaderFilter {
+ /**
+ * @param line the line to modify
+ * @return the trimmed line
+ */
+ public String filter(String line) {
+ if (line.trim().length() == 0) {
+ return null;
+ }
+ return line;
+ }
+ }
+
+ /**
+ * Filter to delete characters
+ */
+ public static class DeleteCharacters extends ProjectComponent
+ implements Filter, ChainableReader {
+ // Attributes
+ /** the list of characters to remove from the input */
+ private String deleteChars = "";
+
+ /**
+ * Set the list of characters to delete
+ * @param deleteChars the list of characters
+ */
+ public void setChars(String deleteChars) {
+ this.deleteChars = resolveBackSlash(deleteChars);
+ }
+
+ /**
+ * remove characters from a string
+ * @param string the string to remove the characters from
+ * @return the converted string
+ */
+ public String filter(String string) {
+ StringBuffer output = new StringBuffer(string.length());
+ for (int i = 0; i < string.length(); ++i) {
+ char ch = string.charAt(i);
+ if (!(isDeleteCharacter(ch))) {
+ output.append(ch);
+ }
+ }
+ return output.toString();
+ }
+
+ /**
+ * factory method to provide a reader that removes
+ * the characters from a reader as part of a filter
+ * chain
+ * @param reader the reader object
+ * @return the chained reader object
+ */
+ public Reader chain(Reader reader) {
+ return new BaseFilterReader(reader) {
+ /**
+ * @return the next non delete character
+ */
+ public int read()
+ throws IOException {
+ while (true) {
+ int c = in.read();
+ if (c == -1) {
+ return c;
+ }
+ if (!(isDeleteCharacter((char) c))) {
+ return c;
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * check if the character c is to be deleted
+ *
+ * @param c char to test
+ * @return true if the supplied char is in the list to be stripped.
+ */
+ private boolean isDeleteCharacter(char c) {
+ for (int d = 0; d < deleteChars.length(); ++d) {
+ if (deleteChars.charAt(d) == c) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ // --------------------------------------------------------
+ // static utility methods - could be placed somewhere else
+ // --------------------------------------------------------
+
+ /**
+ * xml does not do "c" like interpretation of strings.
+ * i.e. \n\r\t etc.
+ * this method processes \n, \r, \t, \f, \\
+ * also subs \s with " \n\r\t\f"
+ * a trailing '\' will be ignored
+ *
+ * @param input raw string with possible embedded '\'s
+ * @return converted string
+ */
+ public static String resolveBackSlash(String input) {
+ return StringUtils.resolveBackSlash(input);
+ }
+
+ /**
+ * convert regex option flag characters to regex options
+ * <ul>
+ * <li>g - Regexp.REPLACE_ALL</li>
+ * <li>i - Regexp.MATCH_CASE_INSENSITIVE</li>
+ * <li>m - Regexp.MATCH_MULTILINE</li>
+ * <li>s - Regexp.MATCH_SINGLELINE</li>
+ * </ul>
+ * @param flags the string containing the flags
+ * @return the Regexp option bits
+ */
+ public static int convertRegexOptions(String flags) {
+ return RegexpUtil.asOptions(flags);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java
new file mode 100644
index 00000000..e72d5f58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java
@@ -0,0 +1,37 @@
+/*
+ * 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.filters;
+
+/**
+ * Like the Unix uniq(1) command, only returns tokens that are
+ * different from their ancestor token.
+ *
+ * <p>This filter is probably most useful if used together with a
+ * sortfilter.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class UniqFilter extends TokenFilter.ChainableReaderFilter {
+
+ private String lastLine = null;
+
+ public String filter(String string) {
+ return lastLine == null || !lastLine.equals(string)
+ ? (lastLine = string) : null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
new file mode 100644
index 00000000..f176c331
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
@@ -0,0 +1,288 @@
+/*
+ * 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.filters.util;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.BaseFilterReader;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.types.AntFilterReader;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Parameterizable;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Process a FilterReader chain.
+ *
+ */
+public final class ChainReaderHelper {
+
+ // default buffer size
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The primary reader to which the reader chain is to be attached.
+ */
+ public Reader primaryReader;
+
+ /**
+ * The size of the buffer to be used.
+ */
+ public int bufferSize = DEFAULT_BUFFER_SIZE;
+
+ /**
+ * Chain of filters
+ */
+ public Vector<FilterChain> filterChains = new Vector<FilterChain>();
+
+ /** The Ant project */
+ private Project project = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Sets the primary reader
+ * @param rdr the reader object
+ */
+ public void setPrimaryReader(Reader rdr) {
+ primaryReader = rdr;
+ }
+
+ /**
+ * Set the project to work with
+ * @param project the current project
+ */
+ public void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get the project
+ *
+ * @return the current project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Sets the buffer size to be used. Defaults to 8192,
+ * if this method is not invoked.
+ * @param size the buffer size to use
+ */
+ public void setBufferSize(int size) {
+ bufferSize = size;
+ }
+
+ /**
+ * Sets the collection of filter reader sets
+ *
+ * @param fchain the filter chains collection
+ */
+ public void setFilterChains(Vector<FilterChain> fchain) {
+ filterChains = fchain;
+ }
+
+ /**
+ * Assemble the reader
+ * @return the assembled reader
+ * @exception BuildException if an error occurs
+ */
+ public Reader getAssembledReader() throws BuildException {
+ if (primaryReader == null) {
+ throw new BuildException("primaryReader must not be null.");
+ }
+
+ Reader instream = primaryReader;
+ final int filterReadersCount = filterChains.size();
+ final Vector<Object> finalFilters = new Vector<Object>();
+ final ArrayList<AntClassLoader> classLoadersToCleanUp =
+ new ArrayList<AntClassLoader>();
+
+ for (int i = 0; i < filterReadersCount; i++) {
+ final FilterChain filterchain =
+ filterChains.elementAt(i);
+ final Vector<Object> filterReaders = filterchain.getFilterReaders();
+ final int readerCount = filterReaders.size();
+ for (int j = 0; j < readerCount; j++) {
+ finalFilters.addElement(filterReaders.elementAt(j));
+ }
+ }
+
+ final int filtersCount = finalFilters.size();
+
+ if (filtersCount > 0) {
+ boolean success = false;
+ try {
+ for (int i = 0; i < filtersCount; i++) {
+ Object o = finalFilters.elementAt(i);
+
+ if (o instanceof AntFilterReader) {
+ instream =
+ expandReader((AntFilterReader) finalFilters.elementAt(i),
+ instream, classLoadersToCleanUp);
+ } else if (o instanceof ChainableReader) {
+ setProjectOnObject(o);
+ instream = ((ChainableReader) o).chain(instream);
+ setProjectOnObject(instream);
+ }
+ }
+ success = true;
+ } finally {
+ if (!success && classLoadersToCleanUp.size() > 0) {
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ }
+ }
+ final Reader finalReader = instream;
+ return classLoadersToCleanUp.size() == 0 ? finalReader
+ : new FilterReader(finalReader) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ }
+
+ /**
+ * helper method to set the project on an object.
+ * the reflection setProject does not work for anonymous/protected/private
+ * classes, even if they have public methods.
+ */
+ private void setProjectOnObject(Object obj) {
+ if (project == null) {
+ return;
+ }
+ if (obj instanceof BaseFilterReader) {
+ ((BaseFilterReader) obj).setProject(project);
+ return;
+ }
+ project.setProjectReference(obj);
+ }
+
+ /**
+ * Deregisters Classloaders from the project so GC can remove them later.
+ */
+ private static void cleanUpClassLoaders(List<AntClassLoader> loaders) {
+ for (Iterator<AntClassLoader> it = loaders.iterator(); it.hasNext();) {
+ it.next().cleanup();
+ }
+ }
+
+ /**
+ * Read data from the reader and return the
+ * contents as a string.
+ * @param rdr the reader object
+ * @return the contents of the file as a string
+ * @exception IOException if an error occurs
+ */
+ public String readFully(Reader rdr)
+ throws IOException {
+ return FileUtils.readFully(rdr, bufferSize);
+ }
+
+ /**
+ * Creates and parameterizes a new FilterReader from a
+ * &lt;filterreader&gt; element.
+ *
+ * @since Ant 1.8.0
+ */
+ private Reader expandReader(final AntFilterReader filter,
+ final Reader ancestor,
+ final List<AntClassLoader> classLoadersToCleanUp) {
+ final String className = filter.getClassName();
+ final Path classpath = filter.getClasspath();
+ final Project pro = filter.getProject();
+ if (className != null) {
+ try {
+ Class<?> clazz = null;
+ if (classpath == null) {
+ clazz = Class.forName(className);
+ } else {
+ AntClassLoader al = pro.createClassLoader(classpath);
+ classLoadersToCleanUp.add(al);
+ clazz = Class.forName(className, true, al);
+ }
+ if (clazz != null) {
+ if (!FilterReader.class.isAssignableFrom(clazz)) {
+ throw new BuildException(className + " does not extend"
+ + " java.io.FilterReader");
+ }
+ final Constructor<?>[] constructors = clazz.getConstructors();
+ int j = 0;
+ boolean consPresent = false;
+ for (; j < constructors.length; j++) {
+ Class<?>[] types = constructors[j].getParameterTypes();
+ if (types.length == 1
+ && types[0].isAssignableFrom(Reader.class)) {
+ consPresent = true;
+ break;
+ }
+ }
+ if (!consPresent) {
+ throw new BuildException(className + " does not define"
+ + " a public constructor"
+ + " that takes in a Reader"
+ + " as its single argument.");
+ }
+ final Reader[] rdr = {ancestor};
+ Reader instream =
+ (Reader) constructors[j].newInstance((Object[]) rdr);
+ setProjectOnObject(instream);
+ if (Parameterizable.class.isAssignableFrom(clazz)) {
+ final Parameter[] params = filter.getParams();
+ ((Parameterizable) instream).setParameters(params);
+ }
+ return instream;
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ throw new BuildException(cnfe);
+ } catch (final InstantiationException ie) {
+ throw new BuildException(ie);
+ } catch (final IllegalAccessException iae) {
+ throw new BuildException(iae);
+ } catch (final InvocationTargetException ite) {
+ throw new BuildException(ite);
+ }
+ }
+ // Ant 1.7.1 and earlier ignore <filterreader> without a
+ // classname attribute, not sure this is a good idea -
+ // backwards compatibility makes it hard to change, though.
+ return ancestor;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java
new file mode 100644
index 00000000..b0c67ce2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java
@@ -0,0 +1,70 @@
+/*
+ * 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.filters.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.ConstantValue;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+/**
+ * Helper class that filters constants from a Java Class
+ *
+ */
+public final class JavaClassHelper {
+ /** System specific line separator. */
+ private static final String LS = System.getProperty("line.separator");
+
+ /**
+ * Get the constants declared in a file as name=value
+ *
+ * @param bytes the class as a array of bytes
+ * @return a StringBuffer contains the name=value pairs
+ * @exception IOException if an error occurs
+ */
+ public static StringBuffer getConstants(final byte[] bytes)
+ throws IOException {
+ final StringBuffer sb = new StringBuffer();
+ final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ final ClassParser parser = new ClassParser(bis, "");
+ final JavaClass javaClass = parser.parse();
+ final Field[] fields = javaClass.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ final Field field = fields[i];
+ if (field != null) {
+ final ConstantValue cv = field.getConstantValue();
+ if (cv != null) {
+ String cvs = cv.toString();
+ //Remove start and end quotes if field is a String
+ if (cvs.startsWith("\"") && cvs.endsWith("\"")) {
+ cvs = cvs.substring(1, cvs.length() - 1);
+ }
+ sb.append(field.getName());
+ sb.append('=');
+ sb.append(cvs);
+ sb.append(LS);
+ }
+ }
+ }
+ return sb;
+ }
+}