diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters')
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><classconstants/></pre> + * Or: + * <pre><filterreader + * classname="org.apache.tools.ant.filters.ClassConstants"/></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> + * <copy todir="build"> + * <fileset dir="src" includes="*.java"/> + * <filterchain> + * <concatfilter prepend="apache-license-java.txt"/> + * </filterchain> + * </copy> + * </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><escapeunicode></pre> + * + * Or: + * + * <pre><filterreader + classname="org.apache.tools.ant.filters.EscapeUnicode"/> + * </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><expandproperties/></pre> + * Or: + * <pre><filterreader + * classname="org.apache.tools.ant.filters.ExpandProperties"/></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> + * <<fixcrlf tab="add" eol="crlf" eof="asis"/> + * </pre> + * + * Or: + * + * <pre> + * <filterreader classname="org.apache.tools.ant.filters.FixCrLfFilter"> + * <param eol="crlf" tab="asis"/> + * </filterreader> + * </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 "<i><b>tab</b></i>" + * 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 "<i><b>tab</b></i>" + * 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><headfilter lines="3"/></pre> + * Or: + * <pre><filterreader classname="org.apache.tools.ant.filters.HeadFilter"> + * <param name="lines" value="3"/> + * </filterreader></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><linecontains> + * <contains value="foo"> + * <contains value="bar"> + * </linecontains></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.LineContains"> + * <param type="contains" value="foo"/> + * <param type="contains" value="bar"/> + * </filterreader></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><linecontainsregexp> + * <regexp pattern="foo*"> + * </linecontainsregexp></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.LineContainsRegExp"> + * <param type="regexp" value="foo*"/> + * </filterreader></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><prefixlines prefix="Foo"/></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.PrefixLines"> + * <param name="prefix" value="Foo"/> + * </filterreader></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><replacetokens begintoken="#" endtoken="#"> + * <token key="DATE" value="${TODAY}"/> + * </replacetokens></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"> + * <param type="tokenchar" name="begintoken" value="#"/> + * <param type="tokenchar" name="endtoken" value="#"/> + * <param type="token" name="DATE" value="${TODAY}"/> + * </filterreader></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> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <sortfilter/> + * </filterchain> + * </copy> + * </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> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <sortfilter reverse="true"/> + * </filterchain> + * </copy> + * </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> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <filterreader classname="org.apache.tools.ant.filters.SortFilter"> + * <param name="comparator" value="org.apache.tools.ant.filters.EvenFirstCmp"/> + * </filterreader> + * </filterchain> + * </copy> + * </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 <b>Comparator</b> { + * public int compare(Object o1, Object o2) { + * ...(omitted) + * } + * } + * </pre> + * + * <p>The example above is equivalent to:</p> + * + * <blockquote><pre> + * <componentdef name="evenfirst" + * classname="org.apache.tools.ant.filters.EvenFirstCmp"/> + * <copy todir="build"> + * <fileset dir="input" includes="*.txt"/> + * <filterchain> + * <sortfilter> + * <evenfirst/> + * </sortfilter> + * </filterchain> + * </copy> + * </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><striplinebreaks/></pre> + * + * Or: + * + * <pre><filterreader + * classname="org.apache.tools.ant.filters.StripLineBreaks"/></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><striplinecomments> + * <comment value="#"/> + * <comment value="--"/> + * <comment value="REM "/> + * <comment value="rem "/> + * <comment value="//"/> + * </striplinecomments></pre> + * + * Or: + * + * <pre><filterreader + * classname="org.apache.tools.ant.filters.StripLineComments"> + * <param type="comment" value="#"/> + * <param type="comment" value="--"/> + * <param type="comment" value="REM "/> + * <param type="comment" value="rem "/> + * <param type="comment" value="//"/> + * </filterreader></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><suffixlines suffix="Foo"/></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.SuffixLines"> + * <param name="suffix" value="Foo"/> + * </filterreader></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><tabstospaces tablength="8"/></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.TabsToSpaces"> + * <param name="tablength" value="8"/> + * </filterreader></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><tailfilter lines="3"/></pre> + * + * Or: + * + * <pre><filterreader classname="org.apache.tools.ant.filters.TailFilter"> + * <param name="lines" value="3"/> + * </filterreader></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&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 + * <filterreader> 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; + } +} |