You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by bu...@apache.org on 2003/09/09 19:12:45 UTC
DO NOT REPLY [Bug 23037] New: -
enhancement of org.apache.tools.ant.types.selectors.ContainsRegexpSelector
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23037>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23037
enhancement of org.apache.tools.ant.types.selectors.ContainsRegexpSelector
Summary: enhancement of
org.apache.tools.ant.types.selectors.ContainsRegexpSelec
tor
Product: Ant
Version: 1.6Alpha (nightly)
Platform: All
OS/Version: All
Status: NEW
Severity: Enhancement
Priority: Other
Component: Other
AssignedTo: dev@ant.apache.org
ReportedBy: ThorstenMoeller@web.de
I wrote a little extension to the ContainsRegexpSelector. Like the
<replaceregexp> Task (org.apache.tools.ant.taskdefs.optional.ReplaceRegExp)
the selector supports two additional parameters: "byline" and "flags". You
will find a short documentation inside the JavaDoc comments.
I want to donate the code to the project.
Thorsten Möller
Here is the CVS patch generated against the Head-Version:
---------------------------------------------------------
Index: ContainsRegexpSelector.java
===================================================================
RCS
file: /home/cvspublic/ant/src/main/org/apache/tools/ant/types/selectors/Contain
sRegexpSelector.java,v
retrieving revision 1.5
diff -u -r1.5 ContainsRegexpSelector.java
--- ContainsRegexpSelector.java 29 Jul 2003 08:37:18 -0000 1.5
+++ ContainsRegexpSelector.java 9 Sep 2003 17:04:35 -0000
@@ -54,140 +54,322 @@
package org.apache.tools.ant.types.selectors;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
+import java.io.BufferedReader;
+import java.io.FileReader;
import java.io.IOException;
-import java.io.InputStreamReader;
-import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.Parameter;
-import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpFactory;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
/**
- * Selector that filters files based on a regular expression.
+ * Selector that filters files based on whether they contain a
+ * particular pattern expressed with a regular expression.
+ * The input file(s) must be able to be properly processed by
+ * a Reader instance. That is, it must be text only, no binary.
+ *
+ * The syntax of the regular expression depends on the implemtation that
+ * you choose to use. The system property <code>ant.regexp.regexpimpl</code>
+ * will be the classname of the implementation that will be used (the default
+ * is <code>org.apache.tools.ant.util.regexp.JakartaOroRegexp</code> and
+ * requires the Jakarta Oro Package).
+ *
+ * <pre>
+ * For jdk <= 1.3, there are two available implementations:
+ * org.apache.tools.ant.util.regexp.JakartaOroRegexp (the default)
+ * Requires the jakarta-oro package
+ *
+ * org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+ * Requires the jakarta-regexp package
*
- * @author <a href="mailto:jvandermeer2@comcast.net">Jay van der Meer</a>
- * @since Ant 1.6
+ * For jdk >= 1.4 an additional implementation is available:
+ * org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp
+ * Requires the jdk 1.4 built in regular expression package.
+ *
+ * Attributes:
+ *
+ * pattern --> The Regular expression to search for
+ * flags --> The options to give to the search. For more
information, consult the Perl5 syntax.
+ * i = Case insensitive match
+ * m = Multiline. Treat the string as multiple lines of
input, using
+ * "^" and "$" as the start or end of any line,
respectively, rather
+ * than start or end of string.
+ * m = Singleline. Treat the string as a single line of
input, using
+ * "." to match any character, including a newline, which
normally,
+ * it would not match.
+ *
+ * byline --> Should files be processed a single line at a time
(default is false)
+ * "true" indicates to perform search on a line by line basis
+ * "false" indicates to perform search on the whole file at
once.
+ *
+ *
+ * @author Thorsten Möller - Thorsten.Moeller@jexam.de
+ *
+ * $Revision: $; $Author: $; $Date: $
*/
-public class ContainsRegexpSelector extends BaseExtendSelector {
+public class ContainsRegexpSelector extends BaseExtendSelector
+{
- private String userProvidedExpression = null;
- private RegularExpression myRegExp = null;
- private Regexp myExpression = null;
- /** Key to used for parameterized custom selector */
- public static final String EXPRESSION_KEY = "expression";
-
- /**
- * Creates a new <code>ContainsRegexpSelector</code> instance.
- */
- public ContainsRegexpSelector() {
- }
-
- /**
- * @return a string describing this object
- */
- public String toString() {
- StringBuffer buf = new StringBuffer(
- "{containsregexpselector expression: ");
- buf.append(userProvidedExpression);
- buf.append("}");
- return buf.toString();
- }
-
- /**
- * The regular expression used to search the file.
- *
- * @param theexpression this must match a line in the file to be selected.
- */
- public void setExpression(String theexpression) {
- this.userProvidedExpression = theexpression;
- }
-
- /**
- * When using this as a custom selector, this method will be called.
- * It translates each parameter into the appropriate setXXX() call.
- *
- * @param parameters the complete set of parameters for this selector
- */
- public void setParameters(Parameter[] parameters) {
- super.setParameters(parameters);
- if (parameters != null) {
- for (int i = 0; i < parameters.length; i++) {
- String paramname = parameters[i].getName();
- if (EXPRESSION_KEY.equalsIgnoreCase(paramname)) {
- setExpression(parameters[i].getValue());
- } else {
- setError("Invalid parameter " + paramname);
- }
- }
- }
- }
-
- /**
- * Checks that an expression was specified.
- *
- */
- public void verifySettings() {
- if (userProvidedExpression == null) {
- setError("The expression attribute is required");
- }
- }
-
- /**
- * Tests a regular expression against each line of text in the file.
- *
- * @param basedir the base directory the scan is being done from
- * @param filename is the name of the file to check
- * @param file is a java.io.File object the selector can use
- * @return whether the file should be selected or not
- */
- public boolean isSelected(File basedir, String filename, File file) {
- String teststr = null;
- BufferedReader in = null;
-
- // throw BuildException on error
-
- validate();
-
- if (file.isDirectory()) {
- return true;
- }
-
- if (myRegExp == null) {
- myRegExp = new RegularExpression();
- myRegExp.setPattern(userProvidedExpression);
- myExpression = myRegExp.getRegexp(getProject());
- }
-
- try {
- in = new BufferedReader(new InputStreamReader(
- new FileInputStream(file)));
-
- teststr = in.readLine();
-
- while (teststr != null) {
-
- if (myExpression.matches(teststr)) {
- return true;
- }
- teststr = in.readLine();
- }
-
- return false;
- } catch (IOException ioe) {
- throw new BuildException("Could not read file " + filename);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (Exception e) {
- throw new BuildException("Could not close file "
- + filename);
- }
- }
- }
- }
+ private boolean byline;
+ private String flags;
+ private Regexp regexp = null;
+ private static final RegexpFactory factory = new RegexpFactory();
+
+ public static final String PATTERN_KEY = "pattern";
+ public static final String FLAGS_KEY = "flags";
+ public static final String BYLINE_KEY = "byline";
+
+ public ContainsRegexpSelector()
+ {
+ this.regexp = factory.newRegexp();
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer("{containsRegexpSelector
pattern: ");
+ buf.append(regexp.getPattern());
+ buf.append(" byline: ");
+ buf.append(Boolean.toString(byline));
+ buf.append(" flags: ");
+ buf.append(flags);
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * Process the file(s) one line at a time.
+ * This is useful if you want to only search for the first occurence
of a regular expression on
+ * each line, which is not easy to do when processing the file as a
whole.
+ * Defaults to <i>false</i>.</td>
+ */
+ public void setByLine(String byline)
+ {
+ Boolean res = Boolean.valueOf(byline);
+ if (res == null)
+ {
+ res = Boolean.FALSE;
+ }
+ this.byline = res.booleanValue();
+ }
+
+ /**
+ * The flags to use when matching the regular expression. For more
+ * information, consult the Perl5 syntax.
+ * <ul>
+ * <li>i : Case Insensitive. Do not consider case in the match
+ * <li>m : Multiline. Treat the string as multiple lines of input,
+ * using "^" and "$" as the start or end of any line,
respectively, rather than start or end of string.
+ * <li>s : Singleline. Treat the string as a single line of input,
using
+ * "." to match any character, including a newline, which
normally, it would not match.
+ *</ul>
+ */
+ public void setFlags(String flags)
+ {
+ this.flags = flags;
+ }
+
+ /**
+ * The pattern to search for within a file.
+ *
+ * @param regexp the string that a file must contain to be selected.
+ */
+ public void setRegexp(String pattern)
+ {
+ this.regexp.setPattern(pattern);
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters)
+ {
+ super.setParameters(parameters);
+ if (parameters != null)
+ {
+ for (int i = 0; i < parameters.length; i++)
+ {
+ String paramname = parameters[i].getName();
+ if (PATTERN_KEY.equalsIgnoreCase(paramname))
+ {
+ setRegexp(parameters[i].getValue());
+ }
+ else if (BYLINE_KEY.equalsIgnoreCase
(paramname))
+ {
+ setByLine(parameters[i].getValue());
+ }
+ else if (FLAGS_KEY.equalsIgnoreCase(paramname))
+ {
+ setFlags(parameters[i].getValue());
+ }
+ else
+ {
+ setError("Invalid parameter " +
paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public void verifySettings()
+ {
+ if (regexp == null)
+ {
+ setError("The pattern attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file)
+ {
+
+ // throw BuildException on error
+ validate();
+
+ if (file.isDirectory())
+ {
+ return true;
+ }
+
+ int options = 0;
+ // if (flags.indexOf('g') != -1) options |=
Regexp.REPLACE_ALL;
+ if (flags.indexOf('i') != -1)
+ options |= Regexp.MATCH_CASE_INSENSITIVE;
+ if (flags.indexOf('m') != -1)
+ options |= Regexp.MATCH_MULTILINE;
+ if (flags.indexOf('s') != -1)
+ options |= Regexp.MATCH_SINGLELINE;
+
+ FileReader r = null;
+ try
+ {
+ r = new FileReader(file);
+ BufferedReader br = new BufferedReader(r);
+ log(
+ "Searching pattern '"
+ + regexp.getPattern()
+ + "' in '"
+ + file.getPath()
+ + "'"
+ + (byline ? " by line" : "")
+ + (flags.length() > 0 ? " with
flags: '" + flags + "'" : "")
+ + ".",
+ Project.MSG_VERBOSE);
+
+ if (byline)
+ {
+ StringBuffer linebuf = new StringBuffer();
+ String line = null;
+ int c;
+ boolean hasCR = false;
+
+ do
+ {
+ c = br.read();
+ if (c == '\r')
+ {
+ if (hasCR)
+ {
+ // second CR -> EOL +
possibly empty line
+ line = linebuf.toString
();
+ if (regexp.matches
(line, options))
+ {
+ return true;
+ }
+ linebuf.setLength(0);
+ // hasCR is still true
(for the second one)
+ }
+ else
+ {
+ // first CR in this
line
+ hasCR = true;
+ }
+ }
+ else if (c == '\n')
+ {
+ // LF -> EOL
+ line = linebuf.toString();
+ if (regexp.matches(line,
options))
+ {
+ return true;
+ }
+ if (hasCR)
+ {
+ hasCR = false;
+ }
+ linebuf.setLength(0);
+ }
+ else
+ { // any other char
+ if ((hasCR) || (c < 0))
+ {
+ // Mac-style linebreak
or EOF (or both)
+ line = linebuf.toString
();
+ if (regexp.matches
(line, options))
+ {
+ return true;
+ }
+ if (hasCR)
+ {
+ hasCR = false;
+ }
+ linebuf.setLength(0);
+ }
+ if (c >= 0)
+ {
+ linebuf.append((char)
c);
+ }
+ }
+ }
+ while (c >= 0);
+ }
+ else
+ {
+ String buf = FileUtils.readFully(br);
+ if (regexp.matches(buf, options))
+ {
+ return true;
+ }
+ }
+ r.close();
+ r = null;
+ }
+ catch (IOException ioe)
+ {
+ throw new BuildException("Could not read file " +
filename);
+ }
+ finally
+ {
+ try
+ {
+ if (r != null)
+ {
+ r.close();
+ }
+ }
+ catch (Exception e)
+ {
+ throw new BuildException("Could not close
file " + filename);
+ }
+ }
+ return false;
+ }
}
-
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org