From e4f0795f1f1d967ba1c2978dfa3b8a3bc2c1b013 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Tue, 28 Nov 2000 15:10:38 +0000 Subject: [PATCH] New Mapper type for regular expression replacements. Currently only jakarta-regexp is supported, at least an ORO implementation will follow. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268257 13f79535-47bb-0310-9956-ffa450edef68 --- bootstrap.bat | 2 +- bootstrap.sh | 1 + build.xml | 7 + .../org/apache/tools/ant/types/Mapper.java | 6 +- .../tools/ant/util/RegexpPatternMapper.java | 155 ++++++++++++++++++ .../ant/util/regexp/JakartaRegexpMatcher.java | 115 +++++++++++++ .../tools/ant/util/regexp/RegexpMatcher.java | 89 ++++++++++ .../util/regexp/JakartaRegexpMatcherTest.java | 72 ++++++++ .../ant/util/regexp/RegexpMatcherTest.java | 126 ++++++++++++++ 9 files changed, 571 insertions(+), 2 deletions(-) create mode 100644 src/main/org/apache/tools/ant/util/RegexpPatternMapper.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java create mode 100644 src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java create mode 100644 src/testcases/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java create mode 100644 src/testcases/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java diff --git a/bootstrap.bat b/bootstrap.bat index 29bfc0e6f..a4a284006 100755 --- a/bootstrap.bat +++ b/bootstrap.bat @@ -44,7 +44,7 @@ mkdir %CLASSDIR% echo. echo ... Compiling Ant Classes -%JAVAC% -d %CLASSDIR% %TOOLS%\tar\*.java %TOOLS%\ant\*.java %TOOLS%\ant\types\*.java %TOOLS%\ant\taskdefs\*.java %TOOLS%\ant\util\*.java +%JAVAC% -d %CLASSDIR% %TOOLS%\tar\*.java %TOOLS%\ant\*.java %TOOLS%\ant\types\*.java %TOOLS%\ant\taskdefs\*.java %TOOLS%\ant\util\*.java %TOOLS%\ant\util\regexp\RegexpMatcher.java echo. echo ... Copying Required Files diff --git a/bootstrap.sh b/bootstrap.sh index e45276e75..0cefbaea5 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -51,6 +51,7 @@ echo ... Compiling Ant Classes ${JAVAC} -d ${CLASSDIR} ${TOOLS}/tar/*.java ${JAVAC} -d ${CLASSDIR} ${TOOLS}/ant/types/*.java ${JAVAC} -d ${CLASSDIR} ${TOOLS}/ant/*.java +${JAVAC} -d ${CLASSDIR} ${TOOLS}/ant/util/regexp/RegexpMatcher.java ${JAVAC} -d ${CLASSDIR} ${TOOLS}/ant/util/*.java ${JAVAC} -d ${CLASSDIR} ${TOOLS}/ant/taskdefs/*.java diff --git a/build.xml b/build.xml index 5a6a772f1..143b85bba 100644 --- a/build.xml +++ b/build.xml @@ -74,6 +74,7 @@ + @@ -113,6 +114,7 @@ + @@ -335,6 +337,7 @@ + @@ -358,6 +361,7 @@ + @@ -365,6 +369,8 @@ + + @@ -376,6 +382,7 @@ + diff --git a/src/main/org/apache/tools/ant/types/Mapper.java b/src/main/org/apache/tools/ant/types/Mapper.java index f99a4056b..5cd16e2d5 100644 --- a/src/main/org/apache/tools/ant/types/Mapper.java +++ b/src/main/org/apache/tools/ant/types/Mapper.java @@ -141,6 +141,8 @@ public class Mapper extends DataType { m.setFrom(from); m.setTo(to); return m; + } catch (BuildException be) { + throw be; } catch (Throwable t) { throw new BuildException(t); } @@ -182,10 +184,12 @@ public class Mapper extends DataType { "org.apache.tools.ant.util.GlobPatternMapper"); implementations.put("merge", "org.apache.tools.ant.util.MergingMapper"); + implementations.put("regexp", + "org.apache.tools.ant.util.RegexpPatternMapper"); } public String[] getValues() { - return new String[] {"identity", "flatten", "glob", "merge"}; + return new String[] {"identity", "flatten", "glob", "merge", "regexp"}; } public String getImplementation() { diff --git a/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java new file mode 100644 index 000000000..21a8e581e --- /dev/null +++ b/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java @@ -0,0 +1,155 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.util.regexp.RegexpMatcher; + +import java.util.Enumeration; +import java.util.Vector; + +/** + * Implementation of FileNameMapper that does regular expression + * replacements. + * + * @author Stefan Bodewig + */ +public class RegexpPatternMapper implements FileNameMapper { + protected RegexpMatcher reg = null; + protected char[] to = null; + protected StringBuffer result = new StringBuffer(); + protected Class regexpMatcherClass = null; + + public RegexpPatternMapper() throws BuildException { + try { + regexpMatcherClass = Class.forName("org.apache.tools.ant.util.regexp.JakartaRegexpMatcher"); + } catch (ClassNotFoundException ce) {} + + if (regexpMatcherClass == null) { + throw new BuildException("No supported regular expression matcher found"); + } + } + + /** + * Sets the "from" pattern. Required. + */ + public void setFrom(String from) throws BuildException { + reg = createMatcher(from); + } + + /** + * Sets the "to" pattern. Required. + */ + public void setTo(String to) { + this.to = to.toCharArray(); + } + + /** + * Returns null if the source file name doesn't match the + * "from" pattern, an one-element array containing the + * translated file otherwise. + */ + public String[] mapFileName(String sourceFileName) { + if (reg == null || to == null + || !reg.matches(sourceFileName)) { + return null; + } + return new String[] {replaceReferences(sourceFileName)}; + } + + /** + * Replace all backreferences in the to pattern with the matched + * groups of the source. + */ + protected String replaceReferences(String source) { + Vector v = reg.getGroups(source); + + result.setLength(0); + for (int i=0; i -1) { + result.append((String) v.elementAt(value)); + } else { + result.append(to[i]); + } + } else { + // XXX - should throw an exception instead? + result.append('\\'); + } + } else { + result.append(to[i]); + } + } + return result.toString(); + } + + /** + * Create an implementation of RegexpMatcher based on the classes + * that can be loaded. + */ + protected RegexpMatcher createMatcher(String pattern) + throws BuildException { + try { + RegexpMatcher rm = (RegexpMatcher) regexpMatcherClass.newInstance(); + rm.setPattern(pattern); + return rm; + } catch (Throwable t) { + throw new BuildException(t); + } + + } +} diff --git a/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java new file mode 100644 index 000000000..1a8f899ab --- /dev/null +++ b/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java @@ -0,0 +1,115 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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.regexp.*; + +import org.apache.tools.ant.BuildException; +import java.util.Vector; + +/** + * Implementation of RegexpMatcher for Jakarta-Regexp. + * + * @author Stefan Bodewig + */ +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); + } + } + + /** + * Get a String representation of the regexp pattern + */ + public String getPattern() { + return pattern; + } + + /** + * Does the given argument match the pattern? + */ + public boolean matches(String argument) { + return reg.match(argument); + } + + /** + * 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 argument) { + if (!matches(argument)) { + 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 java.util.Vector; + +/** + * Interface describing a regular expression matcher. + * + * @author Stefan Bodewig + */ +public interface RegexpMatcher { + + /** + * Set the regexp pattern from the String description. + */ + public void setPattern(String pattern) throws BuildException; + + /** + * Get a String representation of the regexp pattern + */ + public String getPattern(); + + /** + * Does the given argument match the pattern? + */ + public boolean matches(String argument); + + /** + * 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 argument); +} diff --git a/src/testcases/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java b/src/testcases/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java new file mode 100644 index 000000000..c6e79c34c --- /dev/null +++ b/src/testcases/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java @@ -0,0 +1,72 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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; + +/** + * Tests for the jakarta-regexp implementation of the RegexpMatcher interface. + * + * @author Stefan Bodewig + */ +public class JakartaRegexpMatcherTest extends RegexpMatcherTest { + + public RegexpMatcher getImplementation() { + return new JakartaRegexpMatcher(); + } + + public JakartaRegexpMatcherTest(String name) { + super(name); + } + +} diff --git a/src/testcases/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java b/src/testcases/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java new file mode 100644 index 000000000..a337187ae --- /dev/null +++ b/src/testcases/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java @@ -0,0 +1,126 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000 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", "Tomcat", 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 java.util.Vector; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Tests for all implementations of the RegexpMatcher interface. + * + * @author Stefan Bodewig + */ +public abstract class RegexpMatcherTest extends TestCase { + + public abstract RegexpMatcher getImplementation(); + + public RegexpMatcherTest(String name) { + super(name); + } + + public void testMatches() { + RegexpMatcher reg = getImplementation(); + reg.setPattern("aaaa"); + assert("aaaa should match itself", reg.matches("aaaa")); + assert("aaaa should match xaaaa", reg.matches("xaaaa")); + assert("aaaa shouldn\'t match xaaa", !reg.matches("xaaa")); + reg.setPattern("^aaaa"); + assert("^aaaa shouldn\'t match xaaaa", !reg.matches("xaaaa")); + assert("^aaaa should match aaaax", reg.matches("aaaax")); + reg.setPattern("aaaa$"); + assert("aaaa$ shouldn\'t match aaaax", !reg.matches("aaaax")); + assert("aaaa$ should match xaaaa", reg.matches("xaaaa")); + reg.setPattern("[0-9]+"); + assert("[0-9]+ should match 123", reg.matches("123")); + assert("[0-9]+ should match 1", reg.matches("1")); + assert("[0-9]+ shouldn\'t match \'\'", !reg.matches("")); + assert("[0-9]+ shouldn\'t match a", !reg.matches("a")); + reg.setPattern("[0-9]*"); + assert("[0-9]* should match 123", reg.matches("123")); + assert("[0-9]* should match 1", reg.matches("1")); + assert("[0-9]* should match \'\'", reg.matches("")); + assert("[0-9]* should match a", reg.matches("a")); + reg.setPattern("([0-9]+)=\\1"); + assert("([0-9]+)=\\1 should match 1=1", reg.matches("1=1")); + assert("([0-9]+)=\\1 shouldn\'t match 1=2", !reg.matches("1=2")); + } + + public void testGroups() { + RegexpMatcher reg = getImplementation(); + reg.setPattern("aaaa"); + Vector v = reg.getGroups("xaaaa"); + assertEquals("No parens -> no extra groups", 1, v.size()); + assertEquals("Trivial match with no parens", "aaaa", + (String) v.elementAt(0)); + + reg.setPattern("(aaaa)"); + v = reg.getGroups("xaaaa"); + assertEquals("Trivial match with single paren", 2, v.size()); + assertEquals("Trivial match with single paren, full match", "aaaa", + (String) v.elementAt(0)); + assertEquals("Trivial match with single paren, matched paren", "aaaa", + (String) v.elementAt(0)); + + reg.setPattern("(a+)b(b+)"); + v = reg.getGroups("xaabb"); + assertEquals(3, v.size()); + assertEquals("aabb", (String) v.elementAt(0)); + assertEquals("aa", (String) v.elementAt(1)); + assertEquals("b", (String) v.elementAt(2)); + } +}