diff --git a/src/main/org/apache/tools/ant/taskdefs/Javac.java b/src/main/org/apache/tools/ant/taskdefs/Javac.java index 1e0622d15..1fa9cff4e 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Javac.java +++ b/src/main/org/apache/tools/ant/taskdefs/Javac.java @@ -58,6 +58,7 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.*; +import org.apache.tools.ant.util.*; import java.lang.reflect.Method; import java.lang.reflect.Constructor; @@ -89,6 +90,7 @@ import java.util.*; * * @author James Davidson duncan@x180.com * @author Robin Green greenrd@hotmail.com + * @author Stefan Bodewig */ public class Javac extends MatchingTask { @@ -114,7 +116,7 @@ public class Javac extends MatchingTask { private Path extdirs; private static String lSep = System.getProperty("line.separator"); - protected Vector compileList = new Vector(); + protected File[] compileList = new File[0]; /** * Create a nested element for multiple source path @@ -322,10 +324,10 @@ public class Javac extends MatchingTask { } } - if (compileList.size() > 0) { - log("Compiling " + compileList.size() + + if (compileList.length > 0) { + log("Compiling " + compileList.length + " source file" - + (compileList.size() == 1 ? "" : "s") + + (compileList.length == 1 ? "" : "s") + (destDir != null ? " to " + destDir : "")); if (compiler.equalsIgnoreCase("classic")) { @@ -347,7 +349,7 @@ public class Javac extends MatchingTask { * Clear the list of files to be compiled and copied.. */ protected void resetFileLists() { - compileList.removeAllElements(); + compileList = new File[0]; } /** @@ -356,33 +358,11 @@ public class Javac extends MatchingTask { */ protected void scanDir(File srcDir, File destDir, String files[]) { - - long now = (new Date()).getTime(); - - for (int i = 0; i < files.length; i++) { - File srcFile = new File(srcDir, files[i]); - if (files[i].endsWith(".java")) { - File classFile = new File(destDir, files[i].substring(0, - files[i].indexOf(".java")) + ".class"); - - if (srcFile.lastModified() > now) { - log("Warning: file modified in the future: " + - files[i], Project.MSG_WARN); - } - - if (!classFile.exists() || srcFile.lastModified() > classFile.lastModified()) { - if (!classFile.exists()) { - log("Compiling " + srcFile.getPath() + " because class file " - + classFile.getPath() + " does not exist", Project.MSG_DEBUG); - } - else { - log("Compiling " + srcFile.getPath() + " because it is out of date with respect to " - + classFile.getPath(), Project.MSG_DEBUG); - } - compileList.addElement(srcFile.getAbsolutePath()); - } - } - } + GlobPatternMapper m = new GlobPatternMapper(); + m.setFrom("*.java"); + m.setTo("*.class"); + SourceFileScanner sfs = new SourceFileScanner(this); + compileList = sfs.restrictAsFiles(files, srcDir, destDir, m); } // XXX @@ -619,16 +599,15 @@ public class Javac extends MatchingTask { Project.MSG_VERBOSE); StringBuffer niceSourceList = new StringBuffer("File"); - if (compileList.size() != 1) { + if (compileList.length != 1) { niceSourceList.append("s"); } niceSourceList.append(" to be compiled:"); niceSourceList.append(lSep); - Enumeration enum = compileList.elements(); - while (enum.hasMoreElements()) { - String arg = (String)enum.nextElement(); + for (int i=0; i < compileList.length; i++) { + String arg = compileList[i].getAbsolutePath(); cmd.createArgument().setValue(arg); niceSourceList.append(" " + arg + lSep); } diff --git a/src/main/org/apache/tools/ant/util/GlobPatternMapper.java b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java new file mode 100644 index 000000000..5b0c4bcaf --- /dev/null +++ b/src/main/org/apache/tools/ant/util/GlobPatternMapper.java @@ -0,0 +1,156 @@ +/* + * 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; + +/** + * Implementation of FileNameMapper that does simple wildcard pattern + * replacements. + * + *

This does simple translations like *.foo -> *.bar where the + * prefix to .foo will be left unchanged. It only handles a single * + * character, use regular expressions for more complicated + * situations.

+ * + *

This is one of the more useful Mappers, it is used by javac for + * example.

+ * + * @author Stefan Bodewig + */ +public class GlobPatternMapper implements FileNameMapper { + /** + * Part of "from" pattern before the *. + */ + protected String fromPrefix = null; + + /** + * Part of "from" pattern after the *. + */ + protected String fromPostfix = null; + + /** + * Length of the prefix ("from" pattern). + */ + protected int prefixLength; + + /** + * Length of the postfix ("from" pattern). + */ + protected int postfixLength; + + /** + * Part of "to" pattern before the *. + */ + protected String toPrefix = null; + + /** + * Part of "to" pattern after the *. + */ + protected String toPostfix = null; + + /** + * Sets the "from" pattern. Required. + */ + public void setFrom(String from) { + int index = from.lastIndexOf("*"); + if (index == -1) { + fromPrefix = from; + fromPostfix = ""; + } else { + fromPrefix = from.substring(0, index); + fromPostfix = from.substring(index+1); + } + prefixLength = fromPrefix.length(); + postfixLength = fromPostfix.length(); + } + + /** + * Sets the "to" pattern. Required. + */ + public void setTo(String to) { + int index = to.lastIndexOf("*"); + if (index == -1) { + toPrefix = to; + toPostfix = ""; + } else { + toPrefix = to.substring(0, index); + toPostfix = to.substring(index+1); + } + } + + /** + * 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 (fromPrefix == null + || !sourceFileName.startsWith(fromPrefix) + || !sourceFileName.endsWith(fromPostfix)) { + return null; + } + return new String[] {toPrefix + + extractVariablePart(sourceFileName) + + toPostfix}; + } + + /** + * Returns the part of the given string that matches the * in the + * "from" pattern. + */ + protected String extractVariablePart(String name) { + return name.substring(prefixLength, + name.length() - postfixLength); + } +} diff --git a/src/main/org/apache/tools/ant/util/SourceFileScanner.java b/src/main/org/apache/tools/ant/util/SourceFileScanner.java index 8ce61ffca..cdeb7634a 100644 --- a/src/main/org/apache/tools/ant/util/SourceFileScanner.java +++ b/src/main/org/apache/tools/ant/util/SourceFileScanner.java @@ -160,7 +160,7 @@ public class SourceFileScanner { * absolute). */ public File[] restrictAsFiles(String[] files, File srcDir, File destDir, - FileNameMapper mapper) { + FileNameMapper mapper) { String[] res = restrict(files, srcDir, destDir, mapper); File[] result = new File[res.length]; for (int i=0; istefan.bodewig@megabit.net + * @author Stefan Bodewig */ public class ProjectTest extends TestCase { diff --git a/src/testcases/org/apache/tools/ant/util/GlobPatternMapperTest.java b/src/testcases/org/apache/tools/ant/util/GlobPatternMapperTest.java new file mode 100644 index 000000000..7616b3908 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/util/GlobPatternMapperTest.java @@ -0,0 +1,137 @@ +/* + * 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 junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Tests for org.apache.tools.ant.util;GlobPatternMapper. + * + * @author Stefan Bodewig + */ +public class GlobPatternMapperTest extends TestCase { + + public GlobPatternMapperTest(String name) { + super(name); + } + + public void testNoPatternAtAll() { + GlobPatternMapper m = new GlobPatternMapper(); + m.setFrom("foobar"); + m.setTo("baz"); + assertNull("Shouldn\'t match foobar", m.mapFileName("plonk")); + String[] result = m.mapFileName("foobar"); + assertNotNull("Should match foobar", result); + assertEquals("only one result for foobar", 1, result.length); + assertEquals("baz", result[0]); + } + + public void testPostfixOnly() { + GlobPatternMapper m = new GlobPatternMapper(); + m.setFrom("*foo"); + m.setTo("*plonk"); + assertNull("Shouldn\'t match *foo", m.mapFileName("bar.baz")); + String[] result = m.mapFileName("bar.foo"); + assertNotNull("Should match *.foo", result); + assertEquals("only one result for bar.foo", 1, result.length); + assertEquals("bar.plonk", result[0]); + + // Try a silly case + m.setTo("foo*"); + result = m.mapFileName("bar.foo"); + assertEquals("foobar.", result[0]); + } + + public void testPrefixOnly() { + GlobPatternMapper m = new GlobPatternMapper(); + m.setFrom("foo*"); + m.setTo("plonk*"); + assertNull("Shouldn\'t match foo*", m.mapFileName("bar.baz")); + String[] result = m.mapFileName("foo.bar"); + assertNotNull("Should match foo*", result); + assertEquals("only one result for foo.bar", 1, result.length); + assertEquals("plonk.bar", result[0]); + + // Try a silly case + m.setTo("*foo"); + result = m.mapFileName("foo.bar"); + assertEquals(".barfoo", result[0]); + } + + public void testPreAndPostfix() { + GlobPatternMapper m = new GlobPatternMapper(); + m.setFrom("foo*bar"); + m.setTo("plonk*pling"); + assertNull("Shouldn\'t match foo*bar", m.mapFileName("bar.baz")); + String[] result = m.mapFileName("foo.bar"); + assertNotNull("Should match foo*bar", result); + assertEquals("only one result for foo.bar", 1, result.length); + assertEquals("plonk.pling", result[0]); + + // and a little longer + result = m.mapFileName("foo.baz.bar"); + assertNotNull("Should match foo*bar", result); + assertEquals("only one result for foo.baz.bar", 1, result.length); + assertEquals("plonk.baz.pling", result[0]); + + // and a little shorter + result = m.mapFileName("foobar"); + assertNotNull("Should match foo*bar", result); + assertEquals("only one result for foobar", 1, result.length); + assertEquals("plonkpling", result[0]); + } +}