diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java | 712 |
1 files changed, 712 insertions, 0 deletions
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); + } +} |