From ffea0a9f7459b7c64148ae244b22e847bad9128b Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Thu, 25 Oct 2001 15:03:39 +0000 Subject: [PATCH] Rewritten part of the regexp stuff, adding substitution and options. New optional replaceregexp tasks that takes advantage of it. Submitted by: Matthew Inger This doesn't really work (but doesn't break anything either), but I wanted to get the stuff committed now, I will put work into it tomorrow. See mail to the list for details. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269820 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 2 + build.xml | 26 +- .../optional/replaceregexp.properties | 2 + .../taskdefs/optional/replaceregexp.xml | 19 + .../tools/ant/taskdefs/defaults.properties | 1 + .../ant/taskdefs/optional/ReplaceRegExp.java | 423 ++++++++++++++++++ .../tools/ant/types/RegularExpression.java | 161 +++++++ .../apache/tools/ant/types/Substitution.java | 129 ++++++ .../ant/util/regexp/JakartaOroMatcher.java | 98 +++- .../ant/util/regexp/JakartaOroRegexp.java | 99 ++++ .../ant/util/regexp/JakartaRegexpMatcher.java | 72 ++- .../ant/util/regexp/JakartaRegexpRegexp.java | 88 ++++ .../ant/util/regexp/Jdk14RegexpMatcher.java | 87 +++- .../ant/util/regexp/Jdk14RegexpRegexp.java | 106 +++++ .../apache/tools/ant/util/regexp/Regexp.java | 75 ++++ .../tools/ant/util/regexp/RegexpFactory.java | 113 +++++ .../tools/ant/util/regexp/RegexpMatcher.java | 58 ++- .../ant/util/regexp/RegexpMatcherFactory.java | 24 +- .../tools/ant/util/regexp/RegexpUtil.java | 72 +++ 19 files changed, 1596 insertions(+), 59 deletions(-) create mode 100644 src/etc/testcases/taskdefs/optional/replaceregexp.properties create mode 100644 src/etc/testcases/taskdefs/optional/replaceregexp.xml create mode 100644 src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java create mode 100644 src/main/org/apache/tools/ant/types/RegularExpression.java create mode 100644 src/main/org/apache/tools/ant/types/Substitution.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/Regexp.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java diff --git a/WHATSNEW b/WHATSNEW index 17a9215c1..31a74b0c1 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -17,6 +17,8 @@ Fixed bugs: Other changes: -------------- +* New task replaceregexp + * The attributes zipfile, jarfile, warfile and earfile (from the Zip, Jar, War and Ear tasks) have been deprecated and superseded by a new attribute "file". diff --git a/build.xml b/build.xml index 92a6e484f..ede62d8d5 100644 --- a/build.xml +++ b/build.xml @@ -174,6 +174,14 @@ classpathref="classpath"/> + + + + + + + + - - - diff --git a/src/etc/testcases/taskdefs/optional/replaceregexp.properties b/src/etc/testcases/taskdefs/optional/replaceregexp.properties new file mode 100644 index 000000000..4c1c531ed --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/replaceregexp.properties @@ -0,0 +1,2 @@ +OldAbc=Def + diff --git a/src/etc/testcases/taskdefs/optional/replaceregexp.xml b/src/etc/testcases/taskdefs/optional/replaceregexp.xml new file mode 100644 index 000000000..5138c2981 --- /dev/null +++ b/src/etc/testcases/taskdefs/optional/replaceregexp.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index 9b1ff2041..fc269e756 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -123,6 +123,7 @@ jpcovmerge=org.apache.tools.ant.taskdefs.optional.sitraka.CovMerge jpcovreport=org.apache.tools.ant.taskdefs.optional.sitraka.CovReport p4add=org.apache.tools.ant.taskdefs.optional.perforce.P4Add jspc=org.apache.tools.ant.taskdefs.optional.jsp.JspC +replaceregexp=org.apache.tools.ant.taskdefs.optional.ReplaceRegExp # deprecated ant tasks (kept for back compatibility) javadoc2=org.apache.tools.ant.taskdefs.Javadoc diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java new file mode 100644 index 000000000..2894b6534 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java @@ -0,0 +1,423 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.taskdefs.optional; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.util.regexp.Regexp; +import org.apache.tools.ant.types.RegularExpression; +import org.apache.tools.ant.types.Substitution; +import org.apache.tools.ant.types.FileSet; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.PrintWriter; +import java.util.Vector; + +/*** + *
+ * Task to do regular expression string replacements in a text
+ * file.  The input file(s) must be able to be properly processed by
+ * a Reader instance.  That is, they must be text only, no binary.
+ *
+ * The syntax of the regular expression depends on the implemtation that
+ * you choose to use. The system property ant.regexp.regexpimpl
+ * will be the classname of the implementation that will be used (the default
+ * is org.apache.tools.ant.util.regexp.JakartaOroRegexp and
+ * requires the Jakarta Oro Package).
+ *
+ * 
+ * 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
+ *
+ * For jdk <= 1.4, and additional implementation is available:
+ *   org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp
+ *        Requires the jdk 1.4 built in regular expression package.
+ * 
+ * + * Usage: + * + * Task declaration in the project: + * + * <taskdef name="replaceregexp" class="com.sedona.ant.taskdef.ReplaceRegExp" /> + * + * Call Syntax: + * + * <replaceregexp file="file" + * match="pattern" + * replace="pattern" + * flags="options"? + * byline="true|false"? > + * regularexpression? + * substitution? + * fileset* + * </replaceregexp> + * + * NOTE: You must have either the file attribute specified, or at least one fileset subelement + * to operation on. You may not have the file attribute specified if you nest fileset elements + * inside this task. Also, you cannot specify both match and a regular expression subelement at + * the same time, nor can you specify the replace attribute and the substitution subelement at + * the same time. + * + * Attributes: + * + * file --> A single file to operation on (mutually exclusive with the fileset subelements) + * match --> The Perl5 Regular expression to match (see perl5 documentation) + * replace --> The Perl5 Expression replacement string (see perl5 documentation) + * flags --> The Perl5 options to give to the replacement (see perl5 documentation for full list) + * g = Substitute all occurrences. default is to replace only the first one + * i = Case insensitive match + * + * byline --> Should this file be processed a single line at a time (default is false) + * "true" indicates to perform replacement on a line by line basis + * "false" indicates to perform replacement on the whole file at once. + * + * Example: + * + * The following call could be used to replace an old property name in a ".properties" + * file with a new name. In the replace attribute, you can refer to any part of the + * match expression in parenthesis using the syntax appropriate for the specified + * implementation ('$$1' for org.apache.tools.ant.util.regexp.JakartaOroRegexp). + * + * <replaceregexp file="test.properties" + * match="MyProperty=(.*)" + * replace="NewProperty=$$1" + * byline="true" /> + * + *
+ * + * @author Matthew Inger + */ +public class ReplaceRegExp extends Task +{ + // Don't extend SedonaTaskContainer until we can delay building of + // the subtasks so variable of the current token works. + + private File file; + private String flags; + private boolean byline; + private Vector filesets; // Keep jdk 1.1 compliant so others can use this + private RegularExpression regex; + private Substitution subs; + + /*** + * Default Constructor + */ + public ReplaceRegExp() + { + super(); + this.file = null; + this.filesets = new Vector(); + this.flags = ""; + this.byline = false; + + this.regex = null; + this.subs = null; + } + + public void setFile(File file) + { + this.file = file; + } + + public void setMatch(String match) + { + if (regex != null) + throw new BuildException("Only one regular expression is allowed"); + + regex = new RegularExpression(); + regex.setPattern(match); + } + + public void setReplace(String replace) + { + if (subs != null) + throw new BuildException("Only one substitution expression is allowed"); + + subs = new Substitution(); + subs.setExpression(replace); + } + + public void setFlags(String flags) + { + this.flags = flags; + } + + public void setByLine(String byline) + { + Boolean res = Boolean.valueOf(byline); + if (res == null) + res = Boolean.FALSE; + this.byline = res.booleanValue(); + } + + public void addFileset(FileSet set) + { + filesets.add(set); + } + + public RegularExpression createRegularExpression() + { + if (regex != null) + throw new BuildException("Only one regular expression is allowed."); + + regex = new RegularExpression(); + return regex; + } + + public Substitution createSubstitution() + { + if (subs != null) + throw new BuildException("Only one substitution expression is allowed"); + + subs = new Substitution(); + return subs; + } + + + protected String doReplace(RegularExpression r, + Substitution s, + String input, + int options) + { + String res = input; + Regexp regexp = r.getRegexp(project); + + if (regexp.matches(input, options)) + { + res = regexp.substitute(input, s.getExpression(project), options); + } + + return res; + } + + /*** + * Perform the replace on the entire file + */ + protected void doReplace(File f, int options) + throws IOException + { + File parentDir = new File(f.getAbsolutePath()).getParentFile(); + File temp = File.createTempFile("replace", ".txt", parentDir); + + FileReader r = null; + FileWriter w = null; + + try + { + r = new FileReader(f); + w = new FileWriter(temp); + + BufferedReader br = new BufferedReader(r); + BufferedWriter bw = new BufferedWriter(w); + PrintWriter pw = new PrintWriter(bw); + + boolean changes = false; + + log("Replacing pattern '" + regex.getPattern(project) + "' with '" + subs.getExpression(project) + + "' in '" + f.getPath() + "'" + + (byline ? " by line" : "") + + (flags.length() > 0 ? " with flags: '" + flags + "'" : "") + + ".", + Project.MSG_WARN); + + if (byline) + { + LineNumberReader lnr = new LineNumberReader(br); + String line = null; + + while ((line = lnr.readLine()) != null) + { + String res = doReplace(regex, subs, line, options); + if (! res.equals(line)) + changes = true; + + pw.println(res); + } + pw.flush(); + } + else + { + int flen = (int)(f.length()); + char tmpBuf[] = new char[flen]; + int numread = 0; + int totread = 0; + while (numread != -1 && totread < flen) + { + numread = br.read(tmpBuf, totread, flen); + totread += numread; + } + + String buf = new String(tmpBuf); + + String res = doReplace(regex, subs, buf, options); + if (! res.equals(buf)) + changes = true; + + pw.println(res); + pw.flush(); + } + + r.close(); + r = null; + w.close(); + w = null; + + if (changes) + { + f.delete(); + temp.renameTo(f); + } + else + { + temp.delete(); + } + } + finally + { + try { if (r != null) r.close(); } + catch (Exception e) { }; + + try { if (w != null) r.close(); } + catch (Exception e) { }; + } + } + + public void execute() + throws BuildException + { + if (regex == null) + throw new BuildException("No expression to match."); + if (subs == null) + throw new BuildException("Nothing to replace expression with."); + + if (file != null && filesets.size() > 0) + throw new BuildException("You cannot supply the 'file' attribute and filesets at the same time."); + + + 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; + + if (file != null && file.exists()) + { + try + { + doReplace(file, options); + } + catch (IOException e) + { + log("An error occurred processing file: '" + file.getAbsolutePath() + "': " + e.toString(), + Project.MSG_ERR); + } + } + else if (file != null) + { + log("The following file is missing: '" + file.getAbsolutePath() + "'", + Project.MSG_ERR); + } + + int sz = filesets.size(); + for (int i=0;i. + */ +package org.apache.tools.ant.types; + +import java.util.Hashtable; +import java.util.Stack; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.regexp.Regexp; +import org.apache.tools.ant.util.regexp.RegexpFactory; + +/*** + * A regular expression datatype. Keeps an instance of the + * compiled expression for speed purposes. This compiled + * expression is lazily evaluated (it is compiled the first + * time it is needed). The syntax is the dependent on which + * regular expression type you are using. The system property + * "ant.regexp.regexpimpl" will be the classname of the implementation + * that will be used. + * + *
+ * For jdk  <= 1.3, there are two available implementations:
+ *   org.apache.tools.ant.util.regexp.JakartaOroRegexp (the default)
+ *        Based on the jakarta-oro package
+ *
+ *   org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+ *        Based on the jakarta-regexp package
+ *
+ * For jdk <= 1.4, and additional implementation is available:
+ *   org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp
+ *        Based on the jdk 1.4 built in regular expression package.
+ * 
+ * + * @see org.apache.oro.regex.Perl5Compiler + * @see org.apache.regexp.RE + * @see java.util.regex.Pattern + * + *
+ *   <regularexpression [ [id="id"] pattern="expression" | refid="id" ] 
+ *   />
+ * 
+ * + * @see org.apache.tools.ant.util.regexp.Regexp + * @author Matthew Inger mattinger@mindless.com + */ +public class RegularExpression extends DataType +{ + public static final String DATA_TYPE_NAME = "regularexpression"; + + // The regular expression factory + private static final RegexpFactory factory = new RegexpFactory(); + + private Regexp regexp; + + public RegularExpression() + { + this.regexp = factory.newRegexp(); + } + + public void setPattern(String pattern) + { + this.regexp.setPattern(pattern); + } + + /*** + * Gets the pattern string for this RegularExpression in the + * given project. + */ + public String getPattern(Project p) + { + if (isReference()) + return getRef(p).getPattern(p); + + return regexp.getPattern(); + } + + public Regexp getRegexp(Project p) + { + if (isReference()) + return getRef(p).getRegexp(p); + return this.regexp; + } + + /*** + * Get the RegularExpression this reference refers to in + * the given project. Check for circular references too + */ + public RegularExpression getRef(Project p) + { + if (!checked) + { + Stack stk = new Stack(); + stk.push(this); + dieOnCircularReference(stk, p); + } + + + Object o = ref.getReferencedObject(p); + if (!(o instanceof RegularExpression)) + { + String msg = ref.getRefId() + " doesn\'t denote a regularexpression"; + throw new BuildException(msg); + } + else + { + return (RegularExpression) o; + } + } + +} diff --git a/src/main/org/apache/tools/ant/types/Substitution.java b/src/main/org/apache/tools/ant/types/Substitution.java new file mode 100644 index 000000000..ebb817ac5 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/Substitution.java @@ -0,0 +1,129 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.types; + +import java.util.Hashtable; +import java.util.Stack; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.types.DataType; + +/*** + * A regular expression substitution datatype. It is an expression + * that is meant to replace a regular expression. The syntax is the + * same as Perl5. + * @see org.apache.oro.text.regex.Perl5Substitition + * + *
+ *   <substitition [ [id="id"] expression="expression" | refid="id" ] 
+ *   />
+ * 
+ * + * @author Matthew Inger mattinger@mindless.com + */ +public class Substitution extends DataType +{ + public static final String DATA_TYPE_NAME = "substitition"; + + private String expression; + + public Substitution() + { + this.expression = null; + } + + public void setExpression(String expression) + { + this.expression = expression; + } + + /*** + * Gets the pattern string for this RegularExpression in the + * given project. + */ + public String getExpression(Project p) + { + if (isReference()) + return getRef(p).getExpression(p); + + return expression; + } + + /*** + * Get the RegularExpression this reference refers to in + * the given project. Check for circular references too + */ + public Substitution getRef(Project p) + { + if (!checked) + { + Stack stk = new Stack(); + stk.push(this); + dieOnCircularReference(stk, p); + } + + + Object o = ref.getReferencedObject(p); + if (!(o instanceof Substitution)) + { + String msg = ref.getRefId() + " doesn\'t denote a substitution"; + throw new BuildException(msg); + } + else + { + return (Substitution) o; + } + } + +} diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java b/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java index c2baf248e..866bdf6db 100644 --- a/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java +++ b/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java @@ -54,45 +54,77 @@ package org.apache.tools.ant.util.regexp; -import org.apache.oro.text.regex.*; - import org.apache.tools.ant.BuildException; +import org.apache.oro.text.regex.MatchResult; +import org.apache.oro.text.regex.Pattern; +import org.apache.oro.text.regex.Perl5Compiler; +import org.apache.oro.text.regex.Perl5Matcher; +import org.apache.oro.text.regex.Perl5Pattern; +import org.apache.oro.text.regex.Util; + import java.util.Vector; /** * Implementation of RegexpMatcher for Jakarta-ORO. * * @author Stefan Bodewig + * @author Matthew Inger */ public class JakartaOroMatcher implements RegexpMatcher { - protected Perl5Matcher reg = new Perl5Matcher(); - protected Perl5Compiler comp = new Perl5Compiler(); - private Pattern pattern; + private String pattern; + protected final Perl5Compiler compiler = new Perl5Compiler(); + protected final Perl5Matcher matcher = new Perl5Matcher(); + + public JakartaOroMatcher() {} /** * Set the regexp pattern from the String description. */ - public void setPattern(String pattern) throws BuildException { - try { - this.pattern = comp.compile(pattern); - } catch (MalformedPatternException e) { - throw new BuildException(e); - } + public void setPattern(String pattern) { + this.pattern = pattern; } /** * Get a String representation of the regexp pattern */ public String getPattern() { - return pattern.getPattern(); + return this.pattern; + } + + /** + * Get a compiled representation of the regexp pattern + */ + protected Pattern getCompiledPattern(int options) + throws BuildException + { + try + { + // compute the compiler options based on the input options first + Pattern p = compiler.compile(pattern, getCompilerOptions(options)); + return p; + } + catch (Exception e) + { + throw new BuildException(e); + } } /** * Does the given argument match the pattern? */ - public boolean matches(String argument) { - return reg.contains(argument, pattern); + public boolean matches(String argument) throws BuildException { + return matches(argument, MATCH_DEFAULT); + } + + /** + * Does the given argument match the pattern? + */ + public boolean matches(String input, int options) + throws BuildException + { + Pattern p = getCompiledPattern(options); + return matcher.contains(input, p); } /** @@ -101,16 +133,46 @@ public class JakartaOroMatcher implements RegexpMatcher { *

Group 0 will be the full match, the rest are the * parenthesized subexpressions

. */ - public Vector getGroups(String argument) { - if (!matches(argument)) { + public Vector getGroups(String argument) throws BuildException { + return getGroups(argument, MATCH_DEFAULT); + } + + /** + * Returns a Vector of matched groups found in the argument. + * + *

Group 0 will be the full match, the rest are the + * parenthesized subexpressions

. + */ + public Vector getGroups(String input, int options) + throws BuildException + { + if (!matches(input, options)) { return null; } Vector v = new Vector(); - MatchResult mr = reg.getMatch(); - for (int i=0; i. + */ +package org.apache.tools.ant.util.regexp; + +import org.apache.tools.ant.BuildException; +import org.apache.oro.text.regex.Perl5Substitution; +import org.apache.oro.text.regex.Substitution; +import org.apache.oro.text.regex.Util; + +import java.util.Vector; + +/*** + * Regular expression implementation using the Jakarta Oro package + * @author Matthew Inger mattinger@mindless.com + */ +public class JakartaOroRegexp extends JakartaOroMatcher implements Regexp +{ + + public JakartaOroRegexp() + { + super(); + } + + public String substitute(String input, String argument, int options) + throws BuildException + { + // Determine replacement Type + int sOptions = getSubsOptions(options); + + // Do the substitution + Substitution s = new Perl5Substitution(argument, sOptions); + return Util.substitute(matcher, + getCompiledPattern(options), + s, + input); + } + + protected int getSubsOptions(int options) + { + boolean replaceAll = RegexpUtil.hasFlag(options, REPLACE_ALL); + int subsOptions = 1; + if (replaceAll) { + subsOptions = Util.SUBSTITUTE_ALL; + } + return subsOptions; + } + +} diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java index 2207e0cee..c456713c2 100644 --- a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java +++ b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java @@ -63,22 +63,17 @@ import java.util.Vector; * Implementation of RegexpMatcher for Jakarta-Regexp. * * @author Stefan Bodewig + * @author Matthew Inger mattinger@mindless.com */ public class JakartaRegexpMatcher implements RegexpMatcher { - protected RE reg = null; private String pattern; /** * Set the regexp pattern from the String description. */ - public void setPattern(String pattern) throws BuildException { - try { - this.pattern = pattern; - reg = new RE(pattern); - } catch (RESyntaxException e) { - throw new BuildException(e); - } + public void setPattern(String pattern) { + this.pattern = pattern; } /** @@ -88,11 +83,40 @@ public class JakartaRegexpMatcher implements RegexpMatcher { return pattern; } + protected RE getCompiledPattern(int options) + throws BuildException + { + int cOptions = getCompilerOptions(options); + try + { + RE reg = new RE(pattern); + reg.setMatchFlags(cOptions); + return reg; + } + catch (RESyntaxException e) + { + throw new BuildException(e); + } + } + + /** + * Does the given argument match the pattern? + */ + public boolean matches(String argument) throws BuildException { + return matches(argument, MATCH_DEFAULT); + } + /** * Does the given argument match the pattern? */ - public boolean matches(String argument) { - return reg.match(argument); + public boolean matches(String input, int options) + throws BuildException + { + return matches(input, getCompiledPattern(options)); + } + + private boolean matches(String input, RE reg) { + return reg.match(input); } /** @@ -101,15 +125,37 @@ public class JakartaRegexpMatcher implements RegexpMatcher { *

Group 0 will be the full match, the rest are the * parenthesized subexpressions

. */ - public Vector getGroups(String argument) { - if (!matches(argument)) { + public Vector getGroups(String argument) throws BuildException { + return getGroups(argument, MATCH_DEFAULT); + } + + public Vector getGroups(String input, int options) + throws BuildException + { + RE reg = getCompiledPattern(options); + if (!matches(input, reg)) { return null; } Vector v = new Vector(); - for (int i=0; i. + */ +package org.apache.tools.ant.util.regexp; + + +import org.apache.tools.ant.BuildException; +import org.apache.regexp.*; +import java.util.Vector; + +/*** + * Regular expression implementation using the Jakarta Regexp package + * @author Matthew Inger mattinger@mindless.com + */ +public class JakartaRegexpRegexp extends JakartaRegexpMatcher implements Regexp +{ + + public JakartaRegexpRegexp() + { + super(); + } + + protected int getSubsOptions(int options) + { + int subsOptions = RE.REPLACE_FIRSTONLY; + if (RegexpUtil.hasFlag(options, REPLACE_ALL)) + subsOptions = RE.REPLACE_ALL; + return subsOptions; + } + + public String substitute(String input, String argument, int options) + throws BuildException + { + int sOptions = getSubsOptions(options); + RE reg = getCompiledPattern(options); + return reg.subst(input, argument, sOptions); + } +} diff --git a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java index ed2580904..577a4eec2 100644 --- a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java +++ b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java @@ -54,46 +54,77 @@ package org.apache.tools.ant.util.regexp; +import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import org.apache.tools.ant.BuildException; -import java.util.Vector; /** * Implementation of RegexpMatcher for the built-in regexp matcher of * JDK 1.4. * * @author Stefan Bodewig + * @author Matthew Inger mattinger@mindless.com */ public class Jdk14RegexpMatcher implements RegexpMatcher { - private Pattern pattern; + private String pattern; + + public Jdk14RegexpMatcher() {} /** * Set the regexp pattern from the String description. */ - public void setPattern(String pattern) throws BuildException { - try { - this.pattern = Pattern.compile(pattern); - } catch (PatternSyntaxException e) { - throw new BuildException(e); - } + public void setPattern(String pattern) { + this.pattern = pattern; } /** * Get a String representation of the regexp pattern */ public String getPattern() { - return pattern.pattern(); + return pattern; + } + + protected Pattern getCompiledPattern(int options) + throws BuildException + { + int cOptions = getCompilerOptions(options); + try + { + Pattern p = Pattern.compile(this.pattern, cOptions); + return p; + } + catch (PatternSyntaxException e) + { + throw new BuildException(e); + } + } + + /** + * Does the given argument match the pattern? + */ + public boolean matches(String argument) throws BuildException { + return matches(argument, MATCH_DEFAULT); } /** * Does the given argument match the pattern? */ - public boolean matches(String argument) { - return pattern.matcher(argument).find(); + public boolean matches(String input, int options) + throws BuildException + { + try + { + Pattern p = getCompiledPattern(options); + return p.matcher(input).find(); + } + catch (Exception e) + { + throw new BuildException(e); + } } /** @@ -102,16 +133,44 @@ public class Jdk14RegexpMatcher implements RegexpMatcher { *

Group 0 will be the full match, the rest are the * parenthesized subexpressions

. */ - public Vector getGroups(String argument) { - Matcher matcher = pattern.matcher(argument); + public Vector getGroups(String argument) throws BuildException { + return getGroups(argument, MATCH_DEFAULT); + } + + /** + * Returns a Vector of matched groups found in the argument. + * + *

Group 0 will be the full match, the rest are the + * parenthesized subexpressions

. + */ + public Vector getGroups(String input, int options) + throws BuildException + { + Pattern p = getCompiledPattern(options); + Matcher matcher = p.matcher(input); if (!matcher.find()) { return null; } Vector v = new Vector(); - for (int i=0; i<=matcher.groupCount(); i++) { + int cnt = matcher.groupCount(); + for (int i=0; i<=cnt; i++) { v.addElement(matcher.group(i)); } return v; } + protected int getCompilerOptions(int options) + { + int cOptions = 0; + + if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) + cOptions |= Pattern.CASE_INSENSITIVE; + if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) + cOptions |= Pattern.MULTILINE; + if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) + cOptions |= Pattern.DOTALL; + + return cOptions; + } + } diff --git a/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java new file mode 100644 index 000000000..0c5a584d1 --- /dev/null +++ b/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java @@ -0,0 +1,106 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.util.regexp; + + +import org.apache.tools.ant.BuildException; +import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/*** + * Regular expression implementation using the JDK 1.4 regular expression package + * @author Matthew Inger mattinger@mindless.com + */ +public class Jdk14RegexpRegexp extends Jdk14RegexpMatcher implements Regexp +{ + + public Jdk14RegexpRegexp() + { + super(); + } + + protected int getSubsOptions(int options) + { + int subsOptions = REPLACE_FIRST; + if (RegexpUtil.hasFlag(options, REPLACE_ALL)) + subsOptions = REPLACE_ALL; + return subsOptions; + } + + public String substitute(String input, String argument, int options) + throws BuildException + { + int sOptions = getSubsOptions(options); + Pattern p = getCompiledPattern(options); + StringBuffer sb = new StringBuffer(); + + Matcher m = p.matcher(input); + if (RegexpUtil.hasFlag(sOptions, REPLACE_ALL)) + { + sb.append(m.replaceAll(argument)); + } + else + { + boolean res = m.find(); + if (res) + m.appendReplacement(sb, argument); + else + sb.append(input); + } + + return sb.toString(); + } +} diff --git a/src/main/org/apache/tools/ant/util/regexp/Regexp.java b/src/main/org/apache/tools/ant/util/regexp/Regexp.java new file mode 100644 index 000000000..cb03377da --- /dev/null +++ b/src/main/org/apache/tools/ant/util/regexp/Regexp.java @@ -0,0 +1,75 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.util.regexp; + +import org.apache.tools.ant.BuildException; + +/*** + * Interface which represents a regular expression, and the operations + * that can be performed on it. + * + * @author Matthew Inger + */ +public interface Regexp extends RegexpMatcher +{ + /** + * Perform a substitution on the regular expression. + * @param input The string to substitute on + * @param argument The string which defines the substitution + * @param options The list of options for the match and replace. See the + * MATCH_ and REPLACE_ constants above. + */ + String substitute(String input, String argument, int options) + throws BuildException; +} diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java b/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java new file mode 100644 index 000000000..3ebd12360 --- /dev/null +++ b/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java @@ -0,0 +1,113 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.util.regexp; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; + +/*** + * Regular expression factory, which will create Regexp objects. The + * actual implementation class depends on the System or Ant Property: + * ant.regexp.regexpimpl. + * + * @author Matthew Inger mattinger@mindless.com + */ +public class RegexpFactory extends RegexpMatcherFactory +{ + public RegexpFactory() + { + } + + /*** + * Create a new regular expression matcher instance. + */ + public Regexp newRegexp() throws BuildException { + return (Regexp) newRegexp(null); + } + + /*** + * Create a new regular expression matcher instance. + * + * @param p Project whose ant.regexp.regexpimpl property will be used. + */ + public Regexp newRegexp(Project p) throws BuildException { + String systemDefault = null; + if (p == null) { + systemDefault = System.getProperty("ant.regexp.regexpimpl"); + } else { + systemDefault = (String) p.getProperties().get("ant.regexp.regexpimpl"); + } + + if (systemDefault != null) { + return (Regexp)createInstance(systemDefault); + // XXX should we silently catch possible exceptions and try to + // load a different implementation? + } + + try { + return (Regexp)createInstance("org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp"); + } catch (BuildException be) {} + + try { + return (Regexp)createInstance("org.apache.tools.ant.util.regexp.JakartaOroRegexp"); + } catch (BuildException be) {} + + try { + return (Regexp)createInstance("org.apache.tools.ant.util.regexp.JakartaRegexpRegexp"); + } catch (BuildException be) {} + + throw new BuildException("No supported regular expression matcher found"); + } + +} diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java index 398a48355..fc424f7b1 100644 --- a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java +++ b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java @@ -61,9 +61,42 @@ import java.util.Vector; * Interface describing a regular expression matcher. * * @author Stefan Bodewig + * @author Matthew Inger */ public interface RegexpMatcher { + /*** + * Replace only the first occurance of the regular expression + */ + int REPLACE_FIRST = 0x00000001; + + /*** + * Replace all occurances of the regular expression + */ + int REPLACE_ALL = 0x00000010; + + /*** + * Default Mask (case insensitive, neither multiline nor + * singleline specified). + */ + int MATCH_DEFAULT = 0x00000000; + + /*** + * Perform a case insenstive match + */ + int MATCH_CASE_INSENSITIVE = 0x00000100; + + /*** + * Treat the input as a multiline input + */ + int MATCH_MULTILINE = 0x00001000; + + /*** + * Treat the input as singleline input ('.' matches newline) + */ + int MATCH_SINGLELINE = 0x00010000; + + /** * Set the regexp pattern from the String description. */ @@ -72,12 +105,12 @@ public interface RegexpMatcher { /** * Get a String representation of the regexp pattern */ - String getPattern(); + String getPattern() throws BuildException; /** * Does the given argument match the pattern? */ - boolean matches(String argument); + boolean matches(String argument) throws BuildException; /** * Returns a Vector of matched groups found in the argument. @@ -85,5 +118,24 @@ public interface RegexpMatcher { *

Group 0 will be the full match, the rest are the * parenthesized subexpressions

. */ - Vector getGroups(String argument); + Vector getGroups(String argument) throws BuildException; + + /*** + * Does this regular expression match the input, given + * certain options + * @param input The string to check for a match + * @param options The list of options for the match. See the + * MATCH_ constants above. + */ + boolean matches(String input, int options) throws BuildException; + + /*** + * Get the match groups from this regular expression. The return + * type of the elements is always String. + * @param input The string to check for a match + * @param options The list of options for the match. See the + * MATCH_ constants above. + */ + Vector getGroups(String input, int options) throws BuildException; + } diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java index f5f9093b4..e6bc34a83 100644 --- a/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java +++ b/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java @@ -55,6 +55,7 @@ package org.apache.tools.ant.util.regexp; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; /** * Simple Factory Class that produces an implementation of @@ -71,11 +72,30 @@ public class RegexpMatcherFactory { public RegexpMatcherFactory() {} + /*** + * Create a new regular expression instance. + */ public RegexpMatcher newRegexpMatcher() throws BuildException { - String systemDefault = System.getProperty("ant.regexp.matcherimpl"); + return newRegexpMatcher(null); + } + + /*** + * Create a new regular expression instance. + * + * @param p Project whose ant.regexp.regexpimpl property will be used. + */ + public RegexpMatcher newRegexpMatcher(Project p) + throws BuildException { + String systemDefault = null; + if (p == null) { + systemDefault = System.getProperty("ant.regexp.regexpimpl"); + } else { + systemDefault = (String) p.getProperties().get("ant.regexp.regexpimpl"); + } + if (systemDefault != null) { return createInstance(systemDefault); - // XXX should we silently possible exceptions and try to + // XXX should we silently catch possible exceptions and try to // load a different implementation? } diff --git a/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java b/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java new file mode 100644 index 000000000..3e4654427 --- /dev/null +++ b/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java @@ -0,0 +1,72 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.util.regexp; + +/*** + * Regular expression utilities class which handles flag operations + * + * @author Matthew Inger + */ +public class RegexpUtil extends Object +{ + public static final boolean hasFlag(int options, int flag) + { + return ((options & flag) > 0); + } + + public static final int removeFlag(int options, int flag) + { + return (options & (0xFFFFFFFF - flag)); + } +}