New optional replaceregexp tasks that takes advantage of it. Submitted by: Matthew Inger <matti@sedonacorp.com> 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-ffa450edef68master
@@ -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". | |||
@@ -174,6 +174,14 @@ | |||
classpathref="classpath"/> | |||
</and> | |||
</condition> | |||
<condition property="some.regexp.support"> | |||
<or> | |||
<isset property="jdk1.4+" /> | |||
<isset property="jakarta.regexp.present" /> | |||
<isset property="jakarta.oro.present" /> | |||
</or> | |||
</condition> | |||
</target> | |||
<!-- | |||
@@ -210,11 +218,11 @@ | |||
deprecation="${deprecation}" | |||
optimize="${optimize}" > | |||
<classpath refid="classpath" /> | |||
<exclude name="${ant.package}/util/regexp/JakartaRegexpMatcher.java" | |||
<exclude name="${ant.package}/util/regexp/JakartaRegexp*.java" | |||
unless="jakarta.regexp.present" /> | |||
<exclude name="${ant.package}/util/regexp/JakartaOroMatcher.java" | |||
<exclude name="${ant.package}/util/regexp/JakartaOro*.java" | |||
unless="jakarta.oro.present" /> | |||
<exclude name="${ant.package}/util/regexp/Jdk14RegexpMatcher.java" | |||
<exclude name="${ant.package}/util/regexp/Jdk14Regexp*.java" | |||
unless="jdk1.4+" /> | |||
<exclude name="${ant.package}/AntSecurityManager.java" | |||
unless="jdk1.2+" /> | |||
@@ -642,11 +650,11 @@ | |||
<exclude name="org/apache/tools/ant/taskdefs/optional/ANTLRTest.java" | |||
unless="antlr.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaRegexp*Test.java" | |||
unless="jakarta.regexp.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaOro*Test.java" | |||
unless="jakarta.oro.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/Jdk14Regexp*Test.java" | |||
unless="jdk1.4+" /> | |||
<exclude name="org/apache/tools/ant/taskdefs/optional/sitraka/*.java" | |||
unless="jakarta.oro.present" /> | |||
@@ -712,11 +720,11 @@ | |||
<!-- only run these tests if their required libraries are installed --> | |||
<exclude name="org/apache/tools/ant/taskdefs/optional/ANTLRTest.java" | |||
unless="antlr.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaRegexp*Test.java" | |||
unless="jakarta.regexp.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/JakartaOro*Test.java" | |||
unless="jakarta.oro.present" /> | |||
<exclude name="org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java" | |||
<exclude name="org/apache/tools/ant/util/regexp/Jdk14Regexp*Test.java" | |||
unless="jdk1.4+" /> | |||
<exclude name="${optional.package}/ide/VAJExportTest.java" unless="vaj.present" /> | |||
<exclude name="${optional.package}/sitraka/*.java" unless="jakarta.oro.present" /> | |||
@@ -0,0 +1,2 @@ | |||
OldAbc=Def | |||
@@ -0,0 +1,19 @@ | |||
<project name="test" default="def" basedir="."> | |||
<target name="setup"> | |||
<copy file="replaceregexp.properties" tofile="test.properties" /> | |||
</target> | |||
<target name="def" depends="setup"> | |||
<replaceregexp file="test.properties" byline="true"> | |||
<regularexpression pattern="Old(.*)=(.*)" /> | |||
<substitution expression="NewProp=\1\2" /> | |||
</replaceregexp> | |||
</target> | |||
<target name="cleanup"> | |||
<delete file="test.properties" /> | |||
</target> | |||
</project> | |||
@@ -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 | |||
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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; | |||
/*** | |||
* <pre> | |||
* 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 <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 | |||
* | |||
* 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. | |||
* </pre> | |||
* | |||
* 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" /> | |||
* | |||
* </pre> | |||
* | |||
* @author <a href="mailto:mattinger@mindless.com">Matthew Inger</a> | |||
*/ | |||
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<sz;i++) | |||
{ | |||
FileSet fs = (FileSet)(filesets.elementAt(i)); | |||
DirectoryScanner ds = fs.getDirectoryScanner(getProject()); | |||
String files[] = ds.getIncludedFiles(); | |||
for (int j=0;j<files.length;j++) | |||
{ | |||
File f = new File(files[j]); | |||
if (f.exists()) | |||
{ | |||
try | |||
{ | |||
doReplace(f, options); | |||
} | |||
catch (Exception e) | |||
{ | |||
log("An error occurred processing file: '" + f.getAbsolutePath() + "': " + e.toString(), | |||
Project.MSG_ERR); | |||
} | |||
} | |||
else | |||
{ | |||
log("The following file is missing: '" + file.getAbsolutePath() + "'", | |||
Project.MSG_ERR); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,161 @@ | |||
/* | |||
* 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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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. | |||
* | |||
* <pre> | |||
* 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. | |||
* </pre> | |||
* | |||
* @see org.apache.oro.regex.Perl5Compiler | |||
* @see org.apache.regexp.RE | |||
* @see java.util.regex.Pattern | |||
* | |||
* <pre> | |||
* <regularexpression [ [id="id"] pattern="expression" | refid="id" ] | |||
* /> | |||
* </pre> | |||
* | |||
* @see org.apache.tools.ant.util.regexp.Regexp | |||
* @author Matthew Inger <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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; | |||
} | |||
} | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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 | |||
* | |||
* <pre> | |||
* <substitition [ [id="id"] expression="expression" | refid="id" ] | |||
* /> | |||
* </pre> | |||
* | |||
* @author Matthew Inger <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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; | |||
} | |||
} | |||
} |
@@ -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 <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author <a href="mailto:mattinger@mindless.com">Matthew Inger</a> | |||
*/ | |||
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 { | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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. | |||
* | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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<mr.groups(); i++) { | |||
MatchResult mr = matcher.getMatch(); | |||
int cnt = mr.groups(); | |||
for (int i=0; i<cnt; i++) { | |||
v.addElement(mr.group(i)); | |||
} | |||
return v; | |||
} | |||
protected int getCompilerOptions(int options) | |||
{ | |||
int cOptions = Perl5Compiler.DEFAULT_MASK; | |||
if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) { | |||
cOptions |= Perl5Compiler.CASE_INSENSITIVE_MASK; | |||
} | |||
if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) { | |||
cOptions |= Perl5Compiler.MULTILINE_MASK; | |||
} | |||
if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) { | |||
cOptions |= Perl5Compiler.SINGLELINE_MASK; | |||
} | |||
return cOptions; | |||
} | |||
} |
@@ -0,0 +1,99 @@ | |||
/* | |||
* 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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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 <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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; | |||
} | |||
} |
@@ -63,22 +63,17 @@ import java.util.Vector; | |||
* Implementation of RegexpMatcher for Jakarta-Regexp. | |||
* | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author Matthew Inger <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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 { | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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<reg.getParenCount(); i++) { | |||
int cnt = reg.getParenCount(); | |||
for (int i=0; i<cnt; i++) { | |||
v.addElement(reg.getParen(i)); | |||
} | |||
return v; | |||
} | |||
protected int getCompilerOptions(int options) | |||
{ | |||
int cOptions = RE.MATCH_NORMAL; | |||
if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) | |||
cOptions |= RE.MATCH_CASEINDEPENDENT; | |||
if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) | |||
cOptions |= RE.MATCH_MULTILINE; | |||
if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) | |||
cOptions |= RE.MATCH_SINGLELINE; | |||
return cOptions; | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
/* | |||
* 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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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 <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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); | |||
} | |||
} |
@@ -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 <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author Matthew Inger <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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 { | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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. | |||
* | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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; | |||
} | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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 <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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(); | |||
} | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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 <a href="mailto:mattinger@mindless.com">Matthew Inger</a> | |||
*/ | |||
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; | |||
} |
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
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: | |||
* <code>ant.regexp.regexpimpl</code>. | |||
* | |||
* @author Matthew Inger <a href="mailto:mattinger@mindless.com">mattinger@mindless.com</a> | |||
*/ | |||
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"); | |||
} | |||
} |
@@ -61,9 +61,42 @@ import java.util.Vector; | |||
* Interface describing a regular expression matcher. | |||
* | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author <a href="mailto:mattinger@mindless.com">Matthew Inger</a> | |||
*/ | |||
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 { | |||
* <p>Group 0 will be the full match, the rest are the | |||
* parenthesized subexpressions</p>. | |||
*/ | |||
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; | |||
} |
@@ -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? | |||
} | |||
@@ -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 | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant.util.regexp; | |||
/*** | |||
* Regular expression utilities class which handles flag operations | |||
* | |||
* @author <a href="mailto:mattinger@mindless.com">Matthew Inger</a> | |||
*/ | |||
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)); | |||
} | |||
} |