diff options
author | Magesh Umasankar <umagesh@apache.org> | 2002-06-01 12:26:43 +0000 |
---|---|---|
committer | Magesh Umasankar <umagesh@apache.org> | 2002-06-01 12:26:43 +0000 |
commit | ca91f8cb7e4f2bfe1a191dea6126a32649af9565 (patch) | |
tree | 987dedb3cd79ebe75c1c7d7286acffa77470d14c /src | |
parent | f19f07d6e4c72f241057ecfc32d80be21201bbf7 (diff) | |
download | ant-ca91f8cb7e4f2bfe1a191dea6126a32649af9565.tar.gz |
Merge changes made to 1.5 Beta1.
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272826 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
121 files changed, 4618 insertions, 597 deletions
diff --git a/src/etc/testcases/taskdefs/ant.xml b/src/etc/testcases/taskdefs/ant.xml index 4024bc3d2..8a8485a40 100644 --- a/src/etc/testcases/taskdefs/ant.xml +++ b/src/etc/testcases/taskdefs/ant.xml @@ -2,6 +2,10 @@ <project name="ant-test" basedir="." default="test1"> + <path id="inheritable"> + <pathelement path="${java.class.path}" /> + </path> + <target name="cleanup"> <delete file="test1.log" /> <delete file="test2.log" /> @@ -83,4 +87,10 @@ <ant antfile="ant.xml" target="dummy" output="test4.log" dir="ant" /> </target> + + <target name="testRefid"> + <ant antfile="ant/references.xml" inheritRefs="false" target="dummy"> + <property name="testprop" refid="inheritable" /> + </ant> + </target> </project> diff --git a/src/etc/testcases/taskdefs/available.xml b/src/etc/testcases/taskdefs/available.xml index 4bdd7fdd6..ce7a8f833 100644 --- a/src/etc/testcases/taskdefs/available.xml +++ b/src/etc/testcases/taskdefs/available.xml @@ -110,7 +110,14 @@ <target name="test21"> <available property="test" ignoresystemclasses="true" - classname="java.awt.Graphics" classpath="${java.home}/lib/rt.jar:${java.home}/lib/classes.zip"/> + classname="java.awt.Graphics"> + <classpath> + <pathelement location="${java.home}/lib/rt.jar" /> + <pathelement location="${java.home}/lib/classes.jar" /> + <pathelement location="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar" /> + <pathelement location="/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/ui.jar" /> + </classpath> + </available> </target> <target name="test22"> @@ -134,4 +141,14 @@ <delete dir="${user.dir}/test"/> <delete file="${user.dir}/test.jar"/> </target> + + <target name="searchInPathNotThere"> + <available file="not_there" filepath="..:optional" + property="test" /> + </target> + + <target name="searchInPathIsThere"> + <available file="pvcs.xml" filepath="..:optional" + property="test" /> + </target> </project> diff --git a/src/etc/testcases/taskdefs/condition.xml b/src/etc/testcases/taskdefs/condition.xml index 92497afee..a9a576531 100644 --- a/src/etc/testcases/taskdefs/condition.xml +++ b/src/etc/testcases/taskdefs/condition.xml @@ -197,6 +197,7 @@ </condition> <echo>${filesmatch-different}</echo> </target> + <target name="filesmatch-match" > <echo file="match3.txt" message="012345676890" /> @@ -208,6 +209,26 @@ </condition> <echo>${filesmatch-match}</echo> </target> + + <target name="filesmatch-different-sizes"> + <echo file="match5.txt" message="012345676890" /> + <echo file="match6.txt" message="0123456768" /> + <condition property="filesmatch-different-sizes"> + <filesmatch + file1="match5.txt" + file2="match6.txt" /> + </condition> + <echo>${filesmatch-different-sizes}</echo> + </target> + + <target name="filesmatch-different-onemissing"> + <condition property="filesmatch-different-sizes"> + <filesmatch + file1="condition.xml" + file2="missing-file.txt" /> + </condition> + <echo>${filesmatch-different-onemissing}</echo> + </target> <target name="contains" > <condition property="contains"> @@ -332,6 +353,8 @@ <delete file="match2.txt" /> <delete file="match3.txt" /> <delete file="match4.txt" /> + <delete file="match5.txt" /> + <delete file="match6.txt" /> </target> </project> diff --git a/src/etc/testcases/taskdefs/filter.xml b/src/etc/testcases/taskdefs/filter.xml index f2ea3a6f8..f769c02b5 100644 --- a/src/etc/testcases/taskdefs/filter.xml +++ b/src/etc/testcases/taskdefs/filter.xml @@ -42,6 +42,13 @@ </copy> </target> + <target name="test9"> + <filter filtersfile="filterdefs.properties" /> + <copy todir="./taskdefs.tmp" filtering="yes" overwrite="yes"> + <fileset dir="." includes="filter3.txt"/> + </copy> + </target> + <target name="cleanup"> <delete dir="taskdefs.tmp" /> </target> diff --git a/src/etc/testcases/taskdefs/filter3.txt b/src/etc/testcases/taskdefs/filter3.txt new file mode 100644 index 000000000..03d7d29e5 --- /dev/null +++ b/src/etc/testcases/taskdefs/filter3.txt @@ -0,0 +1 @@ +@property@ diff --git a/src/etc/testcases/taskdefs/filterdefs.properties b/src/etc/testcases/taskdefs/filterdefs.properties new file mode 100644 index 000000000..7933956c8 --- /dev/null +++ b/src/etc/testcases/taskdefs/filterdefs.properties @@ -0,0 +1 @@ +property=included diff --git a/src/etc/testcases/taskdefs/fixcrlf/build.xml b/src/etc/testcases/taskdefs/fixcrlf/build.xml index b99f579d4..938f61902 100644 --- a/src/etc/testcases/taskdefs/fixcrlf/build.xml +++ b/src/etc/testcases/taskdefs/fixcrlf/build.xml @@ -109,7 +109,7 @@ includes="input.crlf.utf16" javafiles="false" cr="remove" - encoding="UTF16" + encoding="UnicodeBig" /> </target> diff --git a/src/etc/testcases/taskdefs/manifest.xml b/src/etc/testcases/taskdefs/manifest.xml index 33d7f995f..5d5933dba 100644 --- a/src/etc/testcases/taskdefs/manifest.xml +++ b/src/etc/testcases/taskdefs/manifest.xml @@ -7,14 +7,18 @@ <target name="test1"> <jar file="mftest1.jar" manifest="manifests/test1.mf"/> <unjar src="mftest1.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> <target name="test2"> <jar file="mftest2.jar" manifest="manifests/test2.mf"/> <unjar src="mftest2.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> @@ -48,7 +52,9 @@ </manifest> </jar> <unjar src="mftest8.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> @@ -108,7 +114,9 @@ </manifest> </jar> <unjar src="mftest14.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> @@ -124,7 +132,9 @@ </manifest> </jar> <unjar src="mftestLongLine.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> @@ -141,7 +151,9 @@ </manifest> </jar> <unjar src="mftestOrder1.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> @@ -158,7 +170,9 @@ </manifest> </jar> <unjar src="mftestOrder2.jar" dest="manifests"> - <include name="META-INF/MANIFEST.MF"/> + <patternset> + <include name="META-INF/MANIFEST.MF"/> + </patternset> </unjar> </target> diff --git a/src/etc/testcases/taskdefs/optional/propertyfile.xml b/src/etc/testcases/taskdefs/optional/propertyfile.xml index 75f1af3ee..c55478642 100644 --- a/src/etc/testcases/taskdefs/optional/propertyfile.xml +++ b/src/etc/testcases/taskdefs/optional/propertyfile.xml @@ -3,14 +3,14 @@ <project name="propertyfile-test" default="main" basedir="."> <property file="propertyfile.build.properties"/> - + <target name="main"> <fail> This file is for testing purposes only... @see PropertyFileTest.java for more info. </fail> </target> - + <target name="update-existing-properties"> <propertyfile file="${test.propertyfile}" @@ -22,9 +22,9 @@ <entry key="age" default="${age}" type="int"/> <entry key="date" default="${date}" type="date"/> </propertyfile> - + </target> - + <target name="exercise"> <propertyfile file="${test.propertyfile}"> <entry key="existing.prop" @@ -45,6 +45,10 @@ default="2" operation="+" type="int"/> + <entry key="int.without.value" + default="5" + operation="+" + type="int"/> <entry key="int.without.default" value="1" operation="+" diff --git a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml index 1c9125f83..31a761def 100644 --- a/src/etc/testcases/taskdefs/optional/xmlvalidate.xml +++ b/src/etc/testcases/taskdefs/optional/xmlvalidate.xml @@ -24,5 +24,19 @@ </xmlcatalog> </xmlvalidate> </target> + + <target name="xmlcatalognested"> + <xmlvalidate warn="false"> + <fileset dir="xml" includes="**/about.xml"/> + <xmlcatalog classpath="xml"> + <entity publicID = "bogusImage" + location = "/i/dont/exist.jpg"/> + <xmlcatalog> + <dtd publicID="-//stevo//DTD doc 1.0//EN" + location="doc.dtd"/> + </xmlcatalog> + </xmlcatalog> + </xmlvalidate> + </target> </project> diff --git a/src/etc/testcases/types/selectors.xml b/src/etc/testcases/types/selectors.xml new file mode 100644 index 000000000..087babafa --- /dev/null +++ b/src/etc/testcases/types/selectors.xml @@ -0,0 +1,60 @@ +<?xml version="1.0"?> + +<project name="selectors-test" basedir="." default="setupfiles"> + + <property name="etc.dir" value=".."/> + <property name="test.dir" + value="selectortest"/> + + <target name="setupfiles"> + <mkdir dir="${test.dir}" /> + <mkdir dir="${test.dir}/zip" /> + <mkdir dir="${test.dir}/tar" /> + <mkdir dir="${test.dir}/tar/gz" /> + <mkdir dir="${test.dir}/tar/bz2" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.md5" + tofile="${test.dir}/asf-logo.gif.md5" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.bz2" + tofile="${test.dir}/asf-logo.gif.bz2" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.gz" + tofile="${test.dir}/asf-logo.gif.gz" /> + <copy file="${etc.dir}/taskdefs/expected/copy.filterset.filtered" + tofile="${test.dir}/copy.filterset.filtered" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.zip" + tofile="${test.dir}/zip/asf-logo.gif.zip" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar" + tofile="${test.dir}/tar/asf-logo.gif.tar" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo-huge.tar" + tofile="${test.dir}/tar/asf-logo-huge.tar" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar.gz" + tofile="${test.dir}/tar/gz/asf-logo.gif.tar.gz" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar.bz2" + tofile="${test.dir}/tar/bz2/asf-logo.gif.tar.bz2" /> + <copy file="${etc.dir}/taskdefs/expected/asf-logo-huge.tar.bz2" + tofile="${test.dir}/tar/bz2/asf-logo-huge.tar.bz2" /> + <!-- Make linefeeds consistent between platforms --> + <fixcrlf srcdir="${test.dir}" includes="*.filtered" eol="lf"/> + <!-- Set a known base time for all files --> + <touch datetime="11/21/2001 4:55 AM"> + <fileset dir="${test.dir}"> + <include name="**/*"/> + </fileset> + </touch> + <!-- Then adjust individual ones --> + <touch file="${test.dir}/asf-logo.gif.bz2" + datetime="01/01/2001 12:00 AM"/> + <touch file="${test.dir}/asf-logo.gif.gz" + datetime="04/15/2002 2:30 PM"/> + <touch file="${test.dir}/zip/asf-logo.gif.zip" + datetime="05/10/2002 2:30 PM"/> + <touch file="${test.dir}/tar/asf-logo.gif.tar" + datetime="05/10/2002 2:29 PM"/> + <touch file="${test.dir}/tar/asf-logo-huge.tar" + datetime="05/10/2002 2:29 AM"/> + </target> + + <target name="cleanup"> + <delete dir="${test.dir}" /> + </target> + +</project> diff --git a/src/main/org/apache/tools/ant/AntClassLoader.java b/src/main/org/apache/tools/ant/AntClassLoader.java index 0ccaf32d9..ce9bdbf3c 100644 --- a/src/main/org/apache/tools/ant/AntClassLoader.java +++ b/src/main/org/apache/tools/ant/AntClassLoader.java @@ -391,7 +391,8 @@ public class AntClassLoader extends ClassLoader implements BuildListener { if (LoaderUtils.isContextLoaderAvailable()) { savedContextLoader = LoaderUtils.getContextClassLoader(); ClassLoader loader = this; - if ("only".equals(project.getProperty("build.sysclasspath"))) { + if (project != null + && "only".equals(project.getProperty("build.sysclasspath"))) { loader = this.getClass().getClassLoader(); } LoaderUtils.setContextClassLoader(loader); @@ -1103,9 +1104,7 @@ public class AntClassLoader extends ClassLoader implements BuildListener { * Cleans up any resources held by this classloader. Any open archive * files are closed. */ - public void cleanup() { - pathComponents = null; - project = null; + public synchronized void cleanup() { for (Enumeration e = zipFiles.elements(); e.hasMoreElements();) { ZipFile zipFile = (ZipFile)e.nextElement(); try { @@ -1132,6 +1131,8 @@ public class AntClassLoader extends ClassLoader implements BuildListener { * @param event the buildFinished event */ public void buildFinished(BuildEvent event) { + project.removeBuildListener(this); + project = null; cleanup(); } diff --git a/src/main/org/apache/tools/ant/DirectoryScanner.java b/src/main/org/apache/tools/ant/DirectoryScanner.java index 12b46560e..82134da78 100644 --- a/src/main/org/apache/tools/ant/DirectoryScanner.java +++ b/src/main/org/apache/tools/ant/DirectoryScanner.java @@ -55,12 +55,14 @@ package org.apache.tools.ant; import java.io.File; +import java.io.IOException; import java.util.Vector; import java.util.StringTokenizer; import org.apache.tools.ant.types.selectors.SelectorScanner; import org.apache.tools.ant.types.selectors.FileSelector; import org.apache.tools.ant.types.selectors.SelectorUtils; +import org.apache.tools.ant.util.FileUtils; /** * Class for scanning a directory for files/directories which match certain @@ -229,6 +231,16 @@ public class DirectoryScanner implements FileScanner, SelectorScanner { */ protected boolean isCaseSensitive = true; + /** + * Whether or not symbolic links should be followed. + * + * @since Ant 1.5 + */ + private boolean followSymlinks = true; + + /** Helper. */ + private static final FileUtils fileUtils = FileUtils.newFileUtils(); + /** Whether or not everything tested so far has been included. */ protected boolean everythingIncluded = true; @@ -411,6 +423,15 @@ public class DirectoryScanner implements FileScanner, SelectorScanner { } /** + * Sets whether or not symbolic links should be followed. + * + * @param followSymlinks whether or not symbolic links should be followed + */ + public void setFollowSymlinks(boolean followSymlinks) { + this.followSymlinks = followSymlinks; + } + + /** * Sets the list of include patterns to use. All '/' and '\' characters * are replaced by <code>File.separatorChar</code>, so the separator used * need not match <code>File.separatorChar</code>. @@ -619,6 +640,33 @@ public class DirectoryScanner implements FileScanner, SelectorScanner { + dir.getAbsolutePath()); } + if (!followSymlinks) { + Vector noLinks = new Vector(); + for (int i = 0; i < newfiles.length; i++) { + try { + if (fileUtils.isSymbolicLink(dir, newfiles[i])) { + String name = vpath + newfiles[i]; + File file = new File(dir, newfiles[i]); + if (file.isDirectory()) { + dirsExcluded.addElement(name); + } else { + filesExcluded.addElement(name); + } + } else { + noLinks.addElement(newfiles[i]); + } + } catch (IOException ioe) { + String msg = "IOException caught while checking " + + "for links, couldn't get cannonical path!"; + // will be caught and redirected to Ant's logging system + System.err.println(msg); + noLinks.addElement(newfiles[i]); + } + } + newfiles = new String[noLinks.size()]; + noLinks.copyInto(newfiles); + } + for (int i = 0; i < newfiles.length; i++) { String name = vpath + newfiles[i]; File file = new File(dir, newfiles[i]); diff --git a/src/main/org/apache/tools/ant/Main.java b/src/main/org/apache/tools/ant/Main.java index e637c3e6e..4d8c45b96 100644 --- a/src/main/org/apache/tools/ant/Main.java +++ b/src/main/org/apache/tools/ant/Main.java @@ -851,7 +851,11 @@ public class Main { } printTargets(topNames, topDescriptions, "Main targets:", maxLength); - + //if there were no main targets, we list all subtargets + //as it means nothing has a description + if(topNames.size()==0) { + printSubTargets=true; + } if (printSubTargets) { printTargets(subNames, null, "Subtargets:", 0); } diff --git a/src/main/org/apache/tools/ant/PathTokenizer.java b/src/main/org/apache/tools/ant/PathTokenizer.java index d10f4ee43..e3892f180 100644 --- a/src/main/org/apache/tools/ant/PathTokenizer.java +++ b/src/main/org/apache/tools/ant/PathTokenizer.java @@ -165,7 +165,7 @@ public class PathTokenizer { } else { // we are on NetWare, tokenizing is handled a little differently, // due to the fact that NetWare has multiple-character volume names. - if (token.equals(File.pathSeparator)) { + if (token.equals(File.pathSeparator) || token.equals(":")) { // ignore ";" and get the next token token = tokenizer.nextToken().trim(); } @@ -184,6 +184,7 @@ public class PathTokenizer { token += ":" + oneMore; } else { token += ":"; + lookahead = oneMore; } } // implicit else: ignore the ':' since we have either a diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java index 85eb2b1c1..9e7f81443 100644 --- a/src/main/org/apache/tools/ant/Project.java +++ b/src/main/org/apache/tools/ant/Project.java @@ -151,7 +151,7 @@ public class Project { /** Description for this project (if any). */ private String description; - /** Project properties map (String to String). */ + /** Project properties map (usually String to String). */ private Hashtable properties = new Hashtable(); /** * Map of "user" properties (as created in the Ant task, for example). @@ -1755,7 +1755,7 @@ public class Project { /** * Sends a "build started" event to the build listeners for this project. */ - protected void fireBuildStarted() { + public void fireBuildStarted() { BuildEvent event = new BuildEvent(this); for (int i = 0; i < listeners.size(); i++) { BuildListener listener = (BuildListener) listeners.elementAt(i); @@ -1769,7 +1769,7 @@ public class Project { * failure. May be <code>null</code>, indicating * a successful build. */ - protected void fireBuildFinished(Throwable exception) { + public void fireBuildFinished(Throwable exception) { BuildEvent event = new BuildEvent(this); event.setException(exception); for (int i = 0; i < listeners.size(); i++) { diff --git a/src/main/org/apache/tools/ant/ProjectHelper.java b/src/main/org/apache/tools/ant/ProjectHelper.java index 0ec30cc3c..f1b7e5552 100644 --- a/src/main/org/apache/tools/ant/ProjectHelper.java +++ b/src/main/org/apache/tools/ant/ProjectHelper.java @@ -76,7 +76,7 @@ import org.apache.tools.ant.util.LoaderUtils; * * All helper plugins must provide backward compatiblity with the * original ant patterns, unless a different behavior is explicitely - * specified. For example, if namespace is used on the <project> tag + * specified. For example, if namespace is used on the <project> tag * the helper can expect the entire build file to be namespace-enabled. * Namespaces or helper-specific tags can provide meta-information to * the helper, allowing it to use new ( or different policies ). diff --git a/src/main/org/apache/tools/ant/Task.java b/src/main/org/apache/tools/ant/Task.java index 3bb8024f7..edc2df412 100644 --- a/src/main/org/apache/tools/ant/Task.java +++ b/src/main/org/apache/tools/ant/Task.java @@ -226,13 +226,17 @@ public abstract class Task extends ProjectComponent { /** * Sets the wrapper to be used for runtime configuration. + * + * This method should be used only by the ProjectHelper and ant internals. + * It is public to allow helper plugins to operate on tasks, normal tasks + * should never use it. * * @param wrapper The wrapper to be used for runtime configuration. * May be <code>null</code>, in which case the next call * to getRuntimeConfigurableWrapper will generate a new * wrapper. */ - protected void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper) { + public void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper) { this.wrapper = wrapper; } diff --git a/src/main/org/apache/tools/ant/filters/LineContains.java b/src/main/org/apache/tools/ant/filters/LineContains.java index f4246ca09..9d2d86d8d 100644 --- a/src/main/org/apache/tools/ant/filters/LineContains.java +++ b/src/main/org/apache/tools/ant/filters/LineContains.java @@ -77,7 +77,7 @@ import org.apache.tools.ant.types.Parameter; * <param type="contains" value="bar"/> * </filterreader></pre> * - * This will include only those lines that contain <code>foo</code> and + * This will include only those lines that contain <code>foo</code> and * <code>bar</code>. * * @author <a href="mailto:umagesh@apache.org">Magesh Umasankar</a> @@ -91,7 +91,7 @@ public final class LineContains /** Vector that holds the strings that input lines must contain. */ private Vector contains = new Vector(); - /** + /** * Remaining line to be read from this filter, or <code>null</code> if * the next call to <code>read()</code> should read the original stream * to find the next matching line. @@ -100,7 +100,7 @@ public final class LineContains /** * Constructor for "dummy" instances. - * + * * @see BaseFilterReader#BaseFilterReader() */ public LineContains() { @@ -120,12 +120,12 @@ public final class LineContains /** * Returns the next character in the filtered stream, only including * lines from the original stream which contain all of the specified words. - * + * * @return the next character in the resulting stream, or -1 * if the end of the resulting stream has been reached - * + * * @exception IOException if the underlying stream throws an IOException - * during reading + * during reading */ public final int read() throws IOException { if (!getInitialized()) { @@ -143,21 +143,24 @@ public final class LineContains line = line.substring(1); } } else { + String goodLine = null; line = readLine(); - if (line == null) { - ch = -1; - } else { + while((line != null) && (goodLine == null)) { + goodLine = line; int containsSize = contains.size(); for (int i = 0; i < containsSize; i++) { String containsStr = (String) contains.elementAt(i); if (line.indexOf(containsStr) == -1) { - line = null; + goodLine = null; break; } } - - return read(); + line = readLine(); } + if (goodLine != null) { + line = goodLine; + return read(); + }; } return ch; @@ -165,8 +168,8 @@ public final class LineContains /** * Adds a <code>contains</code> element. - * - * @param contains The <code>contains</code> element to add. + * + * @param contains The <code>contains</code> element to add. * Must not be <code>null</code>. */ public final void addConfiguredContains(final Contains contains) { @@ -176,7 +179,7 @@ public final class LineContains /** * Sets the vector of words which must be contained within a line read * from the original stream in order for it to match this filter. - * + * * @param contains A vector of words which must be contained within a line * in order for it to match in this filter. Must not be <code>null</code>. */ @@ -187,7 +190,7 @@ public final class LineContains /** * Returns the vector of words which must be contained within a line read * from the original stream in order for it to match this filter. - * + * * @return the vector of words which must be contained within a line read * from the original stream in order for it to match this filter. The * returned object is "live" - in other words, changes made to the @@ -200,10 +203,10 @@ public final class LineContains /** * Creates a new LineContains using the passed in * Reader for instantiation. - * + * * @param rdr A Reader object providing the underlying stream. * Must not be <code>null</code>. - * + * * @return a new filter based on this configuration, but filtering * the specified reader */ @@ -238,8 +241,8 @@ public final class LineContains /** * Sets the contains string - * - * @param contains The contains string to set. + * + * @param contains The contains string to set. * Must not be <code>null</code>. */ public final void setValue(String contains) { @@ -248,7 +251,7 @@ public final class LineContains /** * Returns the contains string. - * + * * @return the contains string for this element */ public final String getValue() { diff --git a/src/main/org/apache/tools/ant/filters/ReplaceTokens.java b/src/main/org/apache/tools/ant/filters/ReplaceTokens.java index 19aa14d36..bd0f8b4b5 100644 --- a/src/main/org/apache/tools/ant/filters/ReplaceTokens.java +++ b/src/main/org/apache/tools/ant/filters/ReplaceTokens.java @@ -60,7 +60,7 @@ import java.util.Hashtable; import org.apache.tools.ant.types.Parameter; /** - * Replaces tokens in the original input with user-supplied values + * Replaces tokens in the original input with user-supplied values. * * Example: * diff --git a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java index 73915ca41..80e5d155a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java @@ -276,17 +276,16 @@ public abstract class AbstractCvsTask extends Task { * Need a better cross platform integration with <cvspass>, so * use the same filename. */ - /* But currently we cannot because 'cvs log' is not working - * with a pass file. - if(passFile == null){ + if(passFile == null) { - File defaultPassFile = new File(System.getProperty("user.home") + File defaultPassFile = new File( + System.getProperty("cygwin.user.home", + System.getProperty("user.home")) + File.separatorChar + ".cvspass"); if(defaultPassFile.exists()) this.setPassfile(defaultPassFile); } - */ if (passFile != null) { Environment.Variable var = new Environment.Variable(); @@ -315,6 +314,10 @@ public abstract class AbstractCvsTask extends Task { dest = project.getBaseDir(); } + if (!dest.exists()) { + dest.mkdirs(); + } + exe.setWorkingDirectory(dest); exe.setCommandline(toExecute.getCommandline()); exe.setEnvironment(env.getVariables()); diff --git a/src/main/org/apache/tools/ant/taskdefs/Ant.java b/src/main/org/apache/tools/ant/taskdefs/Ant.java index 8cb591321..2ed50c4bb 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Ant.java +++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java @@ -99,9 +99,9 @@ public class Ant extends Task { /** the basedir where is executed the build file */ private File dir = null; - /** + /** * the build.xml file (can be absolute) in this case dir will be - * ignored + * ignored */ private String antFile = null; @@ -184,12 +184,18 @@ public class Ant extends Task { if (p.getResource() != null) { newP.setResource(p.getResource()); } + if (p.getPrefix() != null) { + newP.setPrefix(p.getPrefix()); + } if (p.getRefid() != null) { newP.setRefid(p.getRefid()); } if (p.getEnvironment() != null) { newP.setEnvironment(p.getEnvironment()); } + if (p.getClasspath() != null) { + newP.setClasspath(p.getClasspath()); + } properties.setElementAt(newP, i); } } @@ -274,7 +280,6 @@ public class Ant extends Task { // basedir and ant.file get special treatment in execute() continue; } - String value = props.get(arg).toString(); if (newProject.getProperty(arg) == null){ // no user property @@ -362,7 +367,7 @@ public class Ant extends Task { getOwningTarget() != null && target.equals(this.getOwningTarget().getName())) { - throw new BuildException("ant task calling its own parent " + throw new BuildException("ant task calling its own parent " + "target"); } @@ -527,7 +532,7 @@ public class Ant extends Task { if (newProject == null) { reinit(); } - Property p = new Property(true); + Property p = new Property(true, getProject()); p.setProject(newProject); p.setTaskName("property"); properties.addElement(p); @@ -560,10 +565,10 @@ public class Ant extends Task { * Set the id that this reference to be stored under in the * new project. * - * @param targetid the id under which this reference will be passed to - * the new project */ + * @param targetid the id under which this reference will be passed to + * the new project */ public void setToRefid(String targetid) { - this.targetid = targetid; + this.targetid = targetid; } /** @@ -572,8 +577,8 @@ public class Ant extends Task { * * @return the id of the reference in the new project. */ - public String getToRefid() { - return targetid; + public String getToRefid() { + return targetid; } } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Available.java b/src/main/org/apache/tools/ant/taskdefs/Available.java index f2ad26667..eba93cd49 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Available.java +++ b/src/main/org/apache/tools/ant/taskdefs/Available.java @@ -185,8 +185,9 @@ public class Available extends Task implements Condition { * * @param file the name of the file which is required. */ - public void setFile(String file) { - this.file = file; + public void setFile(File f) { + this.file = FileUtils.newFileUtils() + .removeLeadingPath(getProject().getBaseDir(), f); } /** @@ -464,19 +465,20 @@ public class Available extends Task implements Condition { try { Class requiredClass = null; if (ignoreSystemclasses) { - loader = new AntClassLoader(null, getProject(), - classpath, false); + loader = new AntClassLoader(null, getProject(), classpath, + false); if (loader != null) { try { - loader.findClass(classname); + requiredClass = loader.findClass(classname); } catch (SecurityException se) { - // class found but restricted name; this is actually - // the case we're looking for, so catch the exception - // and return + // class found but restricted name; this is + // actually the case we're looking for in JDK 1.3+, + // so catch the exception and return return true; } + } else { + return false; } - return false; } else if (loader != null) { requiredClass = loader.loadClass(classname); } else { diff --git a/src/main/org/apache/tools/ant/taskdefs/CVSPass.java b/src/main/org/apache/tools/ant/taskdefs/CVSPass.java index 11ea5c6f7..2669c621c 100644 --- a/src/main/org/apache/tools/ant/taskdefs/CVSPass.java +++ b/src/main/org/apache/tools/ant/taskdefs/CVSPass.java @@ -110,7 +110,10 @@ public class CVSPass extends Task { * Create a CVS task using the default cvspass file location. */ public CVSPass(){ - passFile = new File(System.getProperty("user.home") + "/.cvspass"); + passFile = new File( + System.getProperty("cygwin.user.home", + System.getProperty("user.home")) + + File.separatorChar + ".cvspass"); } /** diff --git a/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java b/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java index 8cc405009..7cff3670a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java @@ -55,6 +55,7 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.condition.Condition; import org.apache.tools.ant.taskdefs.condition.ConditionBase; @@ -114,7 +115,12 @@ public class ConditionTask extends ConditionBase { Condition c = (Condition) getConditions().nextElement(); if (c.eval()) { + log("Condition true; setting "+property+" to "+value, + Project.MSG_DEBUG); getProject().setNewProperty(property, value); + } else { + log("Condition false; not setting "+property, + Project.MSG_DEBUG); } } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Definer.java b/src/main/org/apache/tools/ant/taskdefs/Definer.java index a4d312b68..e4b37630f 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Definer.java +++ b/src/main/org/apache/tools/ant/taskdefs/Definer.java @@ -84,7 +84,11 @@ public abstract class Definer extends Task { private File file; private String resource; private boolean reverseLoader = false; - + private String loaderId = null; + private String classpathId = null; + + private static final String REUSE_LOADER_REF = "ant.reuse.loader"; + public void setReverseLoader(boolean reverseLoader) { this.reverseLoader = reverseLoader; log("The reverseloader attribute is DEPRECATED. It will be removed", @@ -112,9 +116,26 @@ public abstract class Definer extends Task { } public void setClasspathRef(Reference r) { + classpathId=r.getRefId(); createClasspath().setRefid(r); } + /** + * Use the reference to locate the loader. If the loader is not + * found, taskdef will use the specified classpath and register it + * with the specified name. + * + * This allow multiple taskdef/typedef to use the same class loader, + * so they can be used togheter. It eliminate the need to + * put them in the CLASSPATH. + * + * @since Ant 1.5 + */ + public void setLoaderRef(Reference r) { + loaderId = r.getRefId(); + } + + public void execute() throws BuildException { AntClassLoader al = createLoader(); @@ -205,8 +226,32 @@ public abstract class Definer extends Task { } } - private AntClassLoader createLoader() { + // magic property + if (project.getProperty(REUSE_LOADER_REF) != null) { + // Generate the 'reuse' name automatically from the reference. + // This allows <taskdefs> that work on both ant1.4 and ant1.5. + // ( in 1.4 it'll require the task/type to be in classpath if they + // are used togheter ). + if (loaderId == null && classpathId != null) { + loaderId = "ant.loader." + classpathId; + } + } + + // If a loader has been set ( either by loaderRef or magic property ) + if (loaderId != null) { + Object reusedLoader = project.getReference(loaderId); + if (reusedLoader != null) { + if (reusedLoader instanceof AntClassLoader) { + return (AntClassLoader)reusedLoader; + } + // In future the reference object may be the <loader> type + // if( reusedLoader instanceof Loader ) { + // return ((Loader)reusedLoader).getLoader(project); + // } + } + } + AntClassLoader al = null; if (classpath != null) { al = new AntClassLoader(project, classpath, !reverseLoader); @@ -218,6 +263,16 @@ public abstract class Definer extends Task { // task we want to define will never be a Task but always // be wrapped into a TaskAdapter. al.addSystemPackageRoot("org.apache.tools.ant"); + + + // If the loader is new, record it for future uses by other + // task/typedefs + if (loaderId != null) { + if (project.getReference(loaderId) == null) { + project.addReference(loaderId, al); + } + } + return al; } diff --git a/src/main/org/apache/tools/ant/taskdefs/DependSet.java b/src/main/org/apache/tools/ant/taskdefs/DependSet.java index 873c6db65..ed3cc1e1b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/DependSet.java +++ b/src/main/org/apache/tools/ant/taskdefs/DependSet.java @@ -190,6 +190,11 @@ public class DependSet extends MatchingTask { while (enumTargetSets.hasMoreElements()) { FileSet targetFS = (FileSet) enumTargetSets.nextElement(); + if (!targetFS.getDir(getProject()).exists()) { + // this is the same as if it was empty, no target files found + continue; + } + DirectoryScanner targetDS = targetFS.getDirectoryScanner(project); String[] targetFiles = targetDS.getIncludedFiles(); diff --git a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java index fb0170bbd..f45042c49 100644 --- a/src/main/org/apache/tools/ant/taskdefs/ExecTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/ExecTask.java @@ -342,7 +342,7 @@ public class ExecTask extends Task { } if (baos != null) { BufferedReader in = - new BufferedReader(new StringReader(baos.toString())); + new BufferedReader(new StringReader(Execute.toString(baos))); String line = null; StringBuffer val = new StringBuffer(); while ((line = in.readLine()) != null) { diff --git a/src/main/org/apache/tools/ant/taskdefs/Execute.java b/src/main/org/apache/tools/ant/taskdefs/Execute.java index 847d6bdb4..48d1d8338 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Execute.java +++ b/src/main/org/apache/tools/ant/taskdefs/Execute.java @@ -182,8 +182,9 @@ public class Execute { // Just try to use what we got } - BufferedReader in = - new BufferedReader(new StringReader(out.toString())); + BufferedReader in = + new BufferedReader(new StringReader(toString(out))); + String var = null; String line, lineSep = System.getProperty("line.separator"); while ((line = in.readLine()) != null) { @@ -231,6 +232,9 @@ public class Execute { String[] cmd = {"command.com", "/c", "set" }; return cmd; } + } else if (Os.isFamily("z/os")) { + String[] cmd = {"/bin/env"}; + return cmd; } else if (Os.isFamily("unix")) { // Generic UNIX // Alternatively one could use: /bin/sh -c env @@ -248,6 +252,23 @@ public class Execute { } /** + * ByteArrayOutputStream#toString doesn't seem to work reliably on + * OS/390, at least not the way we use it in the execution + * context. + * + * @since Ant 1.5 + */ + public static String toString(ByteArrayOutputStream bos) { + if (Os.isFamily("z/os")) { + try { + bos.toString("Cp1047"); + } catch (java.io.UnsupportedEncodingException e) { + } + } + return bos.toString(); + } + + /** * Creates a new execute object using <code>PumpStreamHandler</code> for * stream handling. */ @@ -325,7 +346,7 @@ public class Execute { /** * Sets the environment variables for the subprocess to launch. * - * @param commandline array of Strings, each element of which has + * @param env array of Strings, each element of which has * an environment variable settings in format <em>key=value</em> */ public void setEnvironment(String[] env) { @@ -365,7 +386,7 @@ public class Execute { * allow the shell to perform additional processing such as associating an * executable with a script, etc * - * @param vmLauncher true if exec should launch through thge VM, + * @param useVMLauncher true if exec should launch through thge VM, * false if the shell should be used to launch the * command. */ @@ -379,7 +400,7 @@ public class Execute { * @param project the Project, only used for logging purposes, may be null. * @param command the command to run * @param env the environment for the command - * @param the working directory for the command + * @param dir the working directory for the command * @param useVM use the built-in exec command for JDK 1.3 if available. * * @since Ant 1.5 @@ -400,7 +421,7 @@ public class Execute { * Runs a process defined by the command line and returns its exit status. * * @return the exit status of the subprocess or <code>INVALID</code> - * @exception java.io.IOExcpetion The exception is thrown, if launching + * @exception java.io.IOException The exception is thrown, if launching * of the subprocess failed */ public int execute() throws IOException { diff --git a/src/main/org/apache/tools/ant/taskdefs/Expand.java b/src/main/org/apache/tools/ant/taskdefs/Expand.java index a4b8405e7..5c32b7a36 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Expand.java +++ b/src/main/org/apache/tools/ant/taskdefs/Expand.java @@ -57,6 +57,7 @@ package org.apache.tools.ant.taskdefs; 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.types.FileSet; import org.apache.tools.ant.types.PatternSet; import org.apache.tools.ant.util.FileUtils; @@ -85,7 +86,7 @@ import java.util.zip.ZipEntry; * name="unjar" * name="unwar" */ -public class Expand extends MatchingTask { +public class Expand extends Task { private File dest; //req private File source; // req private boolean overwrite = true; @@ -298,4 +299,5 @@ public class Expand extends MatchingTask { public void addFileset(FileSet set) { filesets.addElement(set); } + } diff --git a/src/main/org/apache/tools/ant/taskdefs/Get.java b/src/main/org/apache/tools/ant/taskdefs/Get.java index 586cb3237..f4880c2c6 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Get.java +++ b/src/main/org/apache/tools/ant/taskdefs/Get.java @@ -64,6 +64,7 @@ import java.net.HttpURLConnection; import java.util.Date; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; +import org.apache.tools.ant.Project; import org.apache.tools.ant.util.FileUtils; import org.apache.tools.ant.util.JavaEnvUtils; @@ -176,8 +177,13 @@ public class Get extends Task { // test for 401 result (HTTP only) if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) { - log("Not authorized - check " + dest + " for details"); - return; + String message="HTTP Authorization failure"; + if(ignoreErrors) { + log(message,Project.MSG_WARN); + return; + } else { + throw new BuildException(message); + } } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index b887eb7c1..55b94a78c 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -78,7 +78,7 @@ import java.util.Enumeration; * Creates a JAR archive. * * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a> - * @author Brian Deitte + * @author Brian Deitte * <a href="mailto:bdeitte@macromedia.com">bdeitte@macromedia.com</a> * * @since Ant 1.1 @@ -101,7 +101,12 @@ public class Jar extends Zip { * whether to merge fileset manifests; * value is true if filesetmanifest is 'merge' or 'mergewithoutmain' */ - private boolean mergeManifests = false; + private FilesetManifestConfig filesetManifestConfig; + + /** + * Whether to create manifest file on finalizeOutputStream? + */ + private boolean manifestOnFinalize = true; /** * whether to merge the main section of fileset manifests; @@ -151,7 +156,7 @@ public class Jar extends Zip { index = flag; } - public void addConfiguredManifest(Manifest newManifest) + public void addConfiguredManifest(Manifest newManifest) throws ManifestException { if (configuredManifest == null) { configuredManifest = newManifest; @@ -178,8 +183,8 @@ public class Jar extends Zip { r = new FileReader(manifestFile); newManifest = getManifest(r); } catch (IOException e) { - throw new BuildException("Unable to read manifest file: " - + manifestFile + throw new BuildException("Unable to read manifest file: " + + manifestFile + " (" + e.getMessage() + ")", e); } finally { if (r != null) { @@ -200,7 +205,7 @@ public class Jar extends Zip { newManifest = new Manifest(r); } catch (ManifestException e) { log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR); - throw new BuildException("Invalid Manifest: " + manifestFile, + throw new BuildException("Invalid Manifest: " + manifestFile, e, getLocation()); } catch (IOException e) { throw new BuildException("Unable to read manifest file" @@ -210,9 +215,8 @@ public class Jar extends Zip { } public void setFilesetmanifest(FilesetManifestConfig config) { - String filesetManifestConfig = config.getValue(); - mergeManifests = !("skip".equals(filesetManifestConfig)); - mergeManifestsMain = "merge".equals(filesetManifestConfig); + filesetManifestConfig = config; + mergeManifestsMain = "merge".equals(config.getValue()); } public void addMetainf(ZipFileSet fs) { @@ -223,8 +227,16 @@ public class Jar extends Zip { protected void initZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { - String ls = System.getProperty("line.separator"); + if (filesetManifestConfig == null + || filesetManifestConfig.getValue().equals("skip")) { + manifestOnFinalize = false; + createManifest(zOut); + } + } + private void createManifest(ZipOutputStream zOut) + throws IOException, BuildException { + String ls = System.getProperty("line.separator"); try { Manifest finalManifest = Manifest.getDefaultManifest(); @@ -239,7 +251,7 @@ public class Jar extends Zip { } else if (configuredManifest != null) { // configuredManifest is the final merge finalManifest.merge(filesetManifest); - finalManifest.merge(configuredManifest, + finalManifest.merge(configuredManifest, !mergeManifestsMain); } else if (filesetManifest != null) { // filesetManifest is the final (and only) merge @@ -252,9 +264,9 @@ public class Jar extends Zip { finalManifest.merge(manifest, !mergeManifestsMain); } - for (Enumeration e = finalManifest.getWarnings(); + for (Enumeration e = finalManifest.getWarnings(); e.hasMoreElements();) { - log("Manifest warning: " + (String) e.nextElement(), + log("Manifest warning: " + (String) e.nextElement(), Project.MSG_WARN); } @@ -269,9 +281,9 @@ public class Jar extends Zip { finalManifest.write(writer); writer.flush(); - ByteArrayInputStream bais = + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", + super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis(), null); super.initZipOutputStream(zOut); } catch (ManifestException e) { @@ -284,6 +296,10 @@ public class Jar extends Zip { protected void finalizeZipOutputStream(ZipOutputStream zOut) throws IOException, BuildException { + if (manifestOnFinalize) { + createManifest(zOut); + } + if (index) { createIndexList(zOut); } @@ -302,7 +318,7 @@ public class Jar extends Zip { private void createIndexList(ZipOutputStream zOut) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // encoding must be UTF8 as specified in the specs. - PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, + PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "UTF8")); // version-info blankline @@ -338,7 +354,7 @@ public class Jar extends Zip { } writer.flush(); - ByteArrayInputStream bais = + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(), null); } @@ -378,9 +394,10 @@ public class Jar extends Zip { } else { manifest = getManifest(file); } - } else if (mergeManifests) { + } else if (filesetManifestConfig != null && + !filesetManifestConfig.getValue().equals("skip")) { // we add this to our group of fileset manifests - log("Found manifest to merge in file " + file, + log("Found manifest to merge in file " + file, Project.MSG_VERBOSE); try { @@ -391,16 +408,20 @@ public class Jar extends Zip { filesetManifest.merge(newManifest); } } catch (ManifestException e) { - log("Manifest in file " + file + " is invalid: " + log("Manifest in file " + file + " is invalid: " + e.getMessage(), Project.MSG_ERR); throw new BuildException("Invalid Manifest", e, getLocation()); } } else { // assuming 'skip' otherwise - log("File " + file - + " includes a META-INF/MANIFEST.MF which will be ignored. " + // don't warn if skip has been requested explicitly, warn if user + // didn't set the attribute + int logLevel = filesetManifestConfig == null ? + Project.MSG_WARN : Project.MSG_VERBOSE; + log("File " + file + + " includes a META-INF/MANIFEST.MF which will be ignored. " + "To include this file, set filesetManifest to a value other " - + "than 'skip'.", Project.MSG_WARN); + + "than 'skip'.", logLevel); } } @@ -412,34 +433,34 @@ public class Jar extends Zip { * already); false if archive creation should proceed * @exception BuildException if it likes */ - protected boolean isUpToDate(FileScanner[] scanners, File zipFile) + protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException { // need to handle manifest as a special check if (configuredManifest != null || manifestFile == null) { java.util.zip.ZipFile theZipFile = null; try { theZipFile = new java.util.zip.ZipFile(zipFile); - java.util.zip.ZipEntry entry = + java.util.zip.ZipEntry entry = theZipFile.getEntry("META-INF/MANIFEST.MF"); if (entry == null) { - log("Updating jar since the current jar has no manifest", + log("Updating jar since the current jar has no manifest", Project.MSG_VERBOSE); return false; } - Manifest currentManifest = + Manifest currentManifest = new Manifest(new InputStreamReader(theZipFile .getInputStream(entry))); if (configuredManifest == null) { configuredManifest = Manifest.getDefaultManifest(); } if (!currentManifest.equals(configuredManifest)) { - log("Updating jar since jar manifest has changed", + log("Updating jar since jar manifest has changed", Project.MSG_VERBOSE); return false; } } catch (Exception e) { // any problems and we will rebuild - log("Updating jar since cannot read current jar manifest: " + log("Updating jar since cannot read current jar manifest: " + e.getClass().getName() + " - " + e.getMessage(), Project.MSG_VERBOSE); return false; @@ -487,7 +508,7 @@ public class Jar extends Zip { public void reset() { super.reset(); configuredManifest = null; - mergeManifests = false; + filesetManifestConfig = null; mergeManifestsMain = false; manifestFile = null; index = false; diff --git a/src/main/org/apache/tools/ant/taskdefs/Javadoc.java b/src/main/org/apache/tools/ant/taskdefs/Javadoc.java index 499c56cf3..548cd9ced 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Javadoc.java +++ b/src/main/org/apache/tools/ant/taskdefs/Javadoc.java @@ -58,6 +58,8 @@ import java.io.PrintWriter; import java.io.FileWriter; import java.io.IOException; import java.io.FilenameFilter; +import java.net.URL; +import java.net.MalformedURLException; import java.util.Locale; import java.util.Vector; import java.util.Enumeration; @@ -710,6 +712,7 @@ public class Javadoc extends Task { public void setDoclet(String docletName) { if (doclet == null) { doclet = new DocletInfo(); + doclet.setProject(getProject()); } doclet.setName(docletName); } @@ -722,6 +725,7 @@ public class Javadoc extends Task { public void setDocletPath(Path docletPath) { if (doclet == null) { doclet = new DocletInfo(); + doclet.setProject(getProject()); } doclet.setPath(docletPath); } @@ -735,6 +739,7 @@ public class Javadoc extends Task { public void setDocletPathRef(Reference r) { if (doclet == null) { doclet = new DocletInfo(); + doclet.setProject(getProject()); } doclet.createPath().setRefid(r); } @@ -1423,7 +1428,6 @@ public class Javadoc extends Task { * @since 1.5 */ public void addFileset(FileSet fs) { - fs.createInclude().setName("**/*.java"); fileSets.addElement(fs); } @@ -1434,6 +1438,11 @@ public class Javadoc extends Task { Vector packagesToDoc = new Vector(); Path sourceDirs = new Path(getProject()); + + if (sourcePath != null) { + sourceDirs.addExisting(sourcePath); + } + parsePackages(packagesToDoc, sourceDirs); if (packagesToDoc.size() != 0 && sourceDirs.size() == 0) { @@ -1550,21 +1559,32 @@ public class Javadoc extends Task { for (Enumeration e = links.elements(); e.hasMoreElements();) { LinkArgument la = (LinkArgument) e.nextElement(); - if (la.getHref() == null) { - throw new BuildException("Links must provide the URL " - + "to the external class " - + "documentation."); - } + if (la.getHref() == null || la.getHref().length() == 0) { + log("No href was given for the link - skipping", + Project.MSG_VERBOSE); + continue; + } else { + // is the href a valid URL + try { + URL base = new URL("file://."); + URL testHref = new URL(base, la.getHref()); + } catch (MalformedURLException mue) { + // ok - just skip + log("Link href \"" + la.getHref() + + "\" is not a valid url - skipping link", + Project.MSG_WARN); + continue; + } + } + if (la.isLinkOffline()) { File packageListLocation = la.getPackagelistLoc(); if (packageListLocation == null) { throw new BuildException("The package list " - + " location for link " - + la.getHref() - + " must be provided " - + "because the link is " - + "offline"); + + " location for link " + la.getHref() + + " must be provided because the link is " + + "offline"); } File packageList = new File(packageListLocation, "package-list"); @@ -1769,6 +1789,10 @@ public class Javadoc extends Task { Enumeration enum = fileSets.elements(); while (enum.hasMoreElements()) { FileSet fs = (FileSet) enum.nextElement(); + if (!fs.hasPatterns() && !fs.hasSelectors()) { + fs = (FileSet) fs.clone(); + fs.createInclude().setName("**/*.java"); + } File baseDir = fs.getDir(getProject()); DirectoryScanner ds = fs.getDirectoryScanner(getProject()); String[] files = ds.getIncludedFiles(); @@ -1858,6 +1882,8 @@ public class Javadoc extends Task { } } if (containsPackages) { + // We don't need to care for duplicates here, + // Path.list does it for us. sp.createPathElement().setLocation(baseDir); } else { log(baseDir + " doesn\'t contain any packages, dropping it.", diff --git a/src/main/org/apache/tools/ant/taskdefs/LoadFile.java b/src/main/org/apache/tools/ant/taskdefs/LoadFile.java index 05435e2c3..da3bdf914 100644 --- a/src/main/org/apache/tools/ant/taskdefs/LoadFile.java +++ b/src/main/org/apache/tools/ant/taskdefs/LoadFile.java @@ -182,20 +182,25 @@ public final class LoadFile extends Task { instream = new InputStreamReader(bis, encoding); } - ChainReaderHelper crh = new ChainReaderHelper(); - crh.setBufferSize(size); - crh.setPrimaryReader(instream); - crh.setFilterChains(filterChains); - crh.setProject(project); - instream = crh.getAssembledReader(); - - String text = crh.readFully(instream); + String text = ""; + if (size != 0) { + ChainReaderHelper crh = new ChainReaderHelper(); + crh.setBufferSize(size); + crh.setPrimaryReader(instream); + crh.setFilterChains(filterChains); + crh.setProject(project); + instream = crh.getAssembledReader(); + + text = crh.readFully(instream); + } if (text != null) { - project.setNewProperty(property, text); - log("loaded " + text.length() + " characters", - Project.MSG_VERBOSE); - log(property + " := " + text, Project.MSG_DEBUG); + if (text.length() > 0) { + project.setNewProperty(property, text); + log("loaded " + text.length() + " characters", + Project.MSG_VERBOSE); + log(property + " := " + text, Project.MSG_DEBUG); + } } } catch (final IOException ioe) { diff --git a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java index 3e0d83262..cd0f52b93 100644 --- a/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java @@ -59,9 +59,11 @@ import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.types.selectors.*; import java.io.File; import java.util.StringTokenizer; +import java.util.Enumeration; /** * This is an abstract task that should be used by all those tasks that @@ -74,10 +76,11 @@ import java.util.StringTokenizer; * @author Sam Ruby <a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a> * @author Jon S. Stevens <a href="mailto:jon@clearink.com">jon@clearink.com</a> * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> * @since Ant 1.1 */ -public abstract class MatchingTask extends Task { +public abstract class MatchingTask extends Task implements SelectorContainer { protected boolean useDefaultExcludes = true; protected FileSet fileset = new FileSet(); @@ -137,7 +140,7 @@ public abstract class MatchingTask extends Task { /** * Set this to be the items in the base directory that you want to be - * included. You can also specify "*" for the items (ie: items="*") + * included. You can also specify "*" for the items (ie: items="*") * and it will include all the items in the base directory. * * @param itemString the string containing the files to include. @@ -177,29 +180,29 @@ public abstract class MatchingTask extends Task { * @param ignoreString the string containing the files to ignore. */ public void XsetIgnore(String ignoreString) { - log("The ignore attribute is deprecated." + + log("The ignore attribute is deprecated." + "Please use the excludes attribute.", Project.MSG_WARN); if (ignoreString != null && ignoreString.length() > 0) { - StringTokenizer tok = new StringTokenizer(ignoreString, ", ", + StringTokenizer tok = new StringTokenizer(ignoreString, ", ", false); while (tok.hasMoreTokens()) { createExclude().setName("**/" + tok.nextToken().trim() + "/**"); } } } - + /** * Sets whether default exclusions should be used or not. * - * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions + * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions * should be used, "false"|"off"|"no" when they * shouldn't be used. */ public void setDefaultexcludes(boolean useDefaultExcludes) { this.useDefaultExcludes = useDefaultExcludes; } - + /** * Returns the directory scanner needed to access the files to process. */ @@ -213,20 +216,165 @@ public abstract class MatchingTask extends Task { * Sets the name of the file containing the includes patterns. * * @param includesfile A string containing the filename to fetch - * the include patterns from. + * the include patterns from. */ - public void setIncludesfile(File includesfile) { - fileset.setIncludesfile(includesfile); - } + public void setIncludesfile(File includesfile) { + fileset.setIncludesfile(includesfile); + } /** * Sets the name of the file containing the includes patterns. * * @param excludesfile A string containing the filename to fetch - * the include patterns from. + * the include patterns from. + */ + public void setExcludesfile(File excludesfile) { + fileset.setExcludesfile(excludesfile); + } + + /** + * Indicates whether there are any selectors here. + * + * @return whether any selectors are in this container + */ + public boolean hasSelectors() { + return fileset.hasSelectors(); + } + + /** + * Gives the count of the number of selectors in this container + * + * @return the number of selectors in this container + */ + public int selectorCount() { + return fileset.selectorCount(); + } + + /** + * Returns the set of selectors as an array. + * + * @return an array of selectors in this container + */ + public FileSelector[] getSelectors(Project p) { + return fileset.getSelectors(p); + } + + /** + * Returns an enumerator for accessing the set of selectors. + * + * @return an enumerator that goes through each of the selectors + */ + public Enumeration selectorElements() { + return fileset.selectorElements(); + } + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + * @return the selector that was added + */ + public void appendSelector(FileSelector selector) { + fileset.appendSelector(selector); + } + + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public void addSelector(SelectSelector selector) { + fileset.addSelector(selector); + } + + /** + * add an "And" selector entry on the selector list */ - public void setExcludesfile(File excludesfile) { - fileset.setExcludesfile(excludesfile); - } + public void addAnd(AndSelector selector) { + fileset.addAnd(selector); + } + + /** + * add an "Or" selector entry on the selector list + */ + public void addOr(OrSelector selector) { + fileset.addOr(selector); + } + /** + * add a "Not" selector entry on the selector list + */ + public void addNot(NotSelector selector) { + fileset.addNot(selector); + } + + /** + * add a "None" selector entry on the selector list + */ + public void addNone(NoneSelector selector) { + fileset.addNone(selector); + } + + /** + * add a majority selector entry on the selector list + */ + public void addMajority(MajoritySelector selector) { + fileset.addMajority(selector); + } + + /** + * add a selector date entry on the selector list + */ + public void addDate(DateSelector selector) { + fileset.addDate(selector); + } + + /** + * add a selector size entry on the selector list + */ + public void addSize(SizeSelector selector) { + fileset.addSize(selector); + } + + /** + * add a selector filename entry on the selector list + */ + public void addFilename(FilenameSelector selector) { + fileset.addFilename(selector); + } + + /** + * add an extended selector entry on the selector list + */ + public void addCustom(ExtendSelector selector) { + fileset.addCustom(selector); + } + + /** + * add a contains selector entry on the selector list + */ + public void addContains(ContainsSelector selector) { + fileset.addContains(selector); + } + + /** + * add a present selector entry on the selector list + */ + public void addPresent(PresentSelector selector) { + fileset.addPresent(selector); + } + + /** + * add a depth selector entry on the selector list + */ + public void addDepth(DepthSelector selector) { + fileset.addDepth(selector); + } + + /** + * add a depends selector entry on the selector list + */ + public void addDepend(DependSelector selector) { + fileset.addDepend(selector); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Move.java b/src/main/org/apache/tools/ant/taskdefs/Move.java index 0a0b3af9b..c698b8dd1 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Move.java +++ b/src/main/org/apache/tools/ant/taskdefs/Move.java @@ -306,7 +306,7 @@ public class Move extends Copy { } } - if (destFile.exists()) { + if (destFile.exists() && destFile.isFile()) { if (!destFile.delete()) { throw new BuildException("Unable to remove existing " + "file " + destFile); diff --git a/src/main/org/apache/tools/ant/taskdefs/Patch.java b/src/main/org/apache/tools/ant/taskdefs/Patch.java index 34db7aab2..e82b16583 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Patch.java +++ b/src/main/org/apache/tools/ant/taskdefs/Patch.java @@ -171,6 +171,7 @@ public class Patch extends Task { Execute exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN), null); + exe.setCommandline(toExecute.getCommandline()); if (directory != null) { if (directory.exists() && directory.isDirectory()) { @@ -186,6 +187,7 @@ public class Patch extends Task { exe.setWorkingDirectory(getProject().getBaseDir()); } + log(toExecute.describeCommand(), Project.MSG_VERBOSE); try { exe.execute(); } catch (IOException e) { diff --git a/src/main/org/apache/tools/ant/taskdefs/Property.java b/src/main/org/apache/tools/ant/taskdefs/Property.java index f40ac7122..976e4d397 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Property.java +++ b/src/main/org/apache/tools/ant/taskdefs/Property.java @@ -88,18 +88,27 @@ public class Property extends Task { protected String env; protected Reference ref; protected String prefix; + private Project fallback; protected boolean userProperty; // set read-only properties public Property() { - super(); + this(false); } /** * @since Ant 1.5 */ protected Property(boolean userProperty) { + this(userProperty, null); + } + + /** + * @since Ant 1.5 + */ + protected Property(boolean userProperty, Project fallback) { this.userProperty = userProperty; + this.fallback = fallback; } public void setName(String name) { @@ -130,6 +139,9 @@ public class Property extends Task { return file; } + /** + * @since Ant 1.5 + */ public void setPrefix(String prefix) { this.prefix = prefix; if (!prefix.endsWith(".")) { @@ -137,6 +149,13 @@ public class Property extends Task { } } + /** + * @since Ant 1.5 + */ + public String getPrefix() { + return prefix; + } + public void setRefid(Reference ref) { this.ref = ref; } @@ -157,6 +176,9 @@ public class Property extends Task { this.env = env; } + /** + * @since Ant 1.5 + */ public String getEnvironment() { return env; } @@ -181,6 +203,13 @@ public class Property extends Task { } /** + * @since Ant 1.5 + */ + public Path getClasspath() { + return classpath; + } + + /** * @deprecated This was never a supported feature and has been * deprecated without replacement */ @@ -230,10 +259,17 @@ public class Property extends Task { } if ((name != null) && (ref != null)) { - Object obj = ref.getReferencedObject(getProject()); - if (obj != null) { - addProperty(name, obj.toString()); - } + try { + addProperty(name, + ref.getReferencedObject(getProject()).toString()); + } catch (BuildException be) { + if (fallback != null) { + addProperty(name, + ref.getReferencedObject(fallback).toString()); + } else { + throw be; + } + } } } diff --git a/src/main/org/apache/tools/ant/taskdefs/Replace.java b/src/main/org/apache/tools/ant/taskdefs/Replace.java index 29f371efd..1c0718044 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Replace.java +++ b/src/main/org/apache/tools/ant/taskdefs/Replace.java @@ -413,8 +413,14 @@ public class Replace extends MatchingTask { // otherwise, delete the new one if (changes) { ++fileCount; - src.delete(); - temp.renameTo(src); + if (!src.delete()) { + throw new BuildException("Couldn't delete " + src, + getLocation()); + } + if (!temp.renameTo(src)) { + throw new BuildException("Couldn't rename temporary file " + + temp, getLocation()); + } temp = null; } } catch (IOException ioe) { diff --git a/src/main/org/apache/tools/ant/taskdefs/Rmic.java b/src/main/org/apache/tools/ant/taskdefs/Rmic.java index 814f4c9ad..e07f6827a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Rmic.java +++ b/src/main/org/apache/tools/ant/taskdefs/Rmic.java @@ -420,7 +420,7 @@ public class Rmic extends MatchingTask { } if (verify) { - log("Verify has been turned on.", Project.MSG_INFO); + log("Verify has been turned on.", Project.MSG_VERBOSE); } RmicAdapter adapter = RmicAdapterFactory.getRmic(getCompiler(), this); diff --git a/src/main/org/apache/tools/ant/taskdefs/TempFile.java b/src/main/org/apache/tools/ant/taskdefs/TempFile.java index e6e1c54e3..a9c386e65 100644 --- a/src/main/org/apache/tools/ant/taskdefs/TempFile.java +++ b/src/main/org/apache/tools/ant/taskdefs/TempFile.java @@ -63,8 +63,19 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.util.FileUtils; /** - * This task fills a proprerty with a temporary file - * + * This task sets a property to the name of a temporary file. + * Unlike the Java1.2 method to create a temporary file, this task + * does work on Java1.1. Also, it does not actually create the + * temporary file, but it does guarantee that the file did not + * exist when the task was executed. + * <p> + * Examples + * <pre><tempfile property="temp.file" /></pre> + * create a temporary file + * <pre><tempfile property="temp.file" suffix=".xml" /></pre> + * create a temporary file with the .xml suffix. + * <pre><tempfile property="temp.file" destDir="build"/></pre> + * create a temp file in the build subdir *@author steve loughran *@since Ant 1.5 *@ant.task @@ -94,7 +105,7 @@ public class TempFile extends Task { /** - * Sets the property attribute of the TempFile object + * The property you wish to assign the temporary file to * *@param property The property to set */ diff --git a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java index fe18b5328..0f2cab7eb 100644 --- a/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java +++ b/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java @@ -661,20 +661,31 @@ public class XSLTProcess extends MatchingTask implements XSLTLogger { Param p = (Param) e.nextElement(); liaison.addParam(p.getName(), p.getExpression()); } + } catch (Exception ex) { + log("Failed to read stylesheet " + stylesheet, Project.MSG_INFO); + throw new BuildException(ex); + } + + try { // if liaison is a TraxLiason, use XMLCatalog as the entity - // resolver + // resolver and URI resolver if (liaison.getClass().getName().equals(TRAX_LIAISON_CLASS) && xmlCatalog != null) { - log("Configuring TraxLiaison and calling entity resolver", - Project.MSG_DEBUG); + log("Configuring TraxLiaison: setting entity resolver " + + "and setting URI resolver", Project.MSG_DEBUG); Method resolver = liaison.getClass() - .getDeclaredMethod("setEntityResolver", - new Class[] {EntityResolver.class}); + .getDeclaredMethod("setEntityResolver", + new Class[] {EntityResolver.class}); + resolver.invoke(liaison, new Object[] {xmlCatalog}); + + resolver = liaison.getClass() + .getDeclaredMethod("setURIResolver", + new Class[] {loadClass("javax.xml.transform.URIResolver")}); resolver.invoke(liaison, new Object[] {xmlCatalog}); } - } catch (Exception ex) { - log("Failed to read stylesheet " + stylesheet, Project.MSG_INFO); - throw new BuildException(ex); + } catch (Exception e) { + throw new BuildException("Failed to configure XMLCatalog for " + + "TraxLiaison", e); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java b/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java index b7edacb4c..9f1e9db7b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java +++ b/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java @@ -74,10 +74,10 @@ import java.util.Vector; /** * Task that gets property values from a valid xml file. * Example: - * <root-tag myattr="true"> - * <inner-tag someattr="val">Text</inner-tag> - * <a2><a3><a4>false</a4></a3></a2> - * </root-tag> + * <root-tag myattr="true"> + * <inner-tag someattr="val">Text</inner-tag> + * <a2><a3><a4>false</a4></a3></a2> + * </root-tag> * * root-tag(myattr)=true * root-tag.inner-tag=Text diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java index af9951129..35c45a10d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java @@ -115,11 +115,12 @@ public class CompilerAdapterFactory { if (isClassicCompilerSupported) { return new Javac12(); } else { - throw new BuildException("This version of java does " + task.log("This version of java does " + "not support the classic " - + "compiler"); + + "compiler; upgrading to modern", + Project.MSG_WARN); + compilerType="modern"; } - } //on java<=1.3 the modern falls back to classic if it is not found //but on java>=1.4 we just bail out early diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java index cd8426228..1e3105b99 100644 --- a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java @@ -397,7 +397,10 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { /** * Do the compile with the specified arguments. * @param args - arguments to pass to process on command line - * @param firstFileName - index of the first source file in args + * @param firstFileName - index of the first source file in args, + * if the index is negative, no temporary file will ever be + * created, but this may hit the command line length limit on your + * system. */ protected int executeExternalCompile(String[] args, int firstFileName) { String[] commandArray = null; @@ -411,12 +414,13 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { * POSIX seems to define a lower limit of 4k, so use a temporary * file if the total length of the command line exceeds this limit. */ - if (Commandline.toString(args).length() > 4096) { + if (Commandline.toString(args).length() > 4096 + && firstFileName >= 0) { PrintWriter out = null; try { String userDirName = System.getProperty("user.dir"); File userDir = new File(userDirName); - tmpFile = fileUtils.createTempFile("jikes", "", userDir); + tmpFile = fileUtils.createTempFile("files", "", userDir); out = new PrintWriter(new FileWriter(tmpFile)); for (int i = firstFileName; i < args.length; i++) { out.println(args[i]); @@ -459,6 +463,13 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { } /** + * @deprecated use org.apache.tools.ant.types.Path#addExtdirs instead + */ + protected void addExtdirsToClasspath(Path classpath) { + classpath.addExtdirs(extdirs); + } + + /** * Adds the command line arguments specifc to the current implementation. */ protected void addCurrentCompilerArgs(Commandline cmd) { diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java index 66cc65194..66297763b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java +++ b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java @@ -75,7 +75,7 @@ public class JavacExternal extends DefaultCompilerAdapter { Commandline cmd = new Commandline(); cmd.setExecutable(getJavac().getJavacExecutable()); setupModernJavacCommandlineSwitches(cmd); - int firstFileName = cmd.size(); + int firstFileName = assumeJava11() ? -1 : cmd.size(); logAndAddFilesToCompile(cmd); return diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Http.java b/src/main/org/apache/tools/ant/taskdefs/condition/Http.java index 3849dfb7e..5c63f9965 100644 --- a/src/main/org/apache/tools/ant/taskdefs/condition/Http.java +++ b/src/main/org/apache/tools/ant/taskdefs/condition/Http.java @@ -67,7 +67,7 @@ import java.net.URL; /** * Condition to wait for a HTTP request to succeed. Its attribute(s) are: * url - the URL of the request. - * + * errorsBeginAt - number at which errors begin at; default=400. * @author <a href="mailto:denis@network365.com">Denis Hennessy</a> * @since Ant 1.5 */ @@ -78,6 +78,12 @@ public class Http extends ProjectComponent implements Condition { spec = url; } + private int errorsBeginAt=400; + + public void SetErrorsBeginAt(int errorsBeginAt) { + this.errorsBeginAt=errorsBeginAt; + } + public boolean eval() throws BuildException { if (spec == null) { throw new BuildException("No url specified in http condition"); @@ -92,7 +98,7 @@ public class Http extends ProjectComponent implements Condition { int code = http.getResponseCode(); log("Result code for " + spec + " was " + code, Project.MSG_VERBOSE); - if (code > 0 && code < 500) { + if (code > 0 && code < errorsBeginAt) { return true; } else { return false; diff --git a/src/main/org/apache/tools/ant/taskdefs/condition/Os.java b/src/main/org/apache/tools/ant/taskdefs/condition/Os.java index 7e6d2548e..8ddd457af 100644 --- a/src/main/org/apache/tools/ant/taskdefs/condition/Os.java +++ b/src/main/org/apache/tools/ant/taskdefs/condition/Os.java @@ -99,6 +99,7 @@ public class Os implements Condition { * <li>unix</li> * <li>windows</li> * <li>win9x</li> + * <li>z/os</li> * </ul> */ public void setFamily(String f) {family = f.toLowerCase(Locale.US);} @@ -221,6 +222,9 @@ public class Os implements Condition { !(osName.indexOf("nt") >= 0 || osName.indexOf("2000") >= 0 || osName.indexOf("xp") >= 0); + } else if (family.equals("z/os")) { + isFamily = osName.indexOf("z/os") > -1 + || osName.indexOf("os/390") > -1; } else { throw new BuildException( "Don\'t know how to detect os family \"" diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index f13ae69c7..92a7d4805 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -69,6 +69,7 @@ cvschangelog=org.apache.tools.ant.taskdefs.cvslib.ChangeLogTask buildnumber=org.apache.tools.ant.taskdefs.BuildNumber concat=org.apache.tools.ant.taskdefs.Concat cvstagdiff=org.apache.tools.ant.taskdefs.cvslib.CvsTagDiff +tempfile=org.apache.tools.ant.taskdefs.TempFile # optional tasks script=org.apache.tools.ant.taskdefs.optional.Script @@ -113,6 +114,7 @@ telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask csc=org.apache.tools.ant.taskdefs.optional.dotnet.CSharp ilasm=org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet +wsdltodotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet stylebook=org.apache.tools.ant.taskdefs.optional.StyleBook test=org.apache.tools.ant.taskdefs.optional.Test pvcs=org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs @@ -163,6 +165,7 @@ jarlib-display=org.apache.tools.ant.taskdefs.optional.extension.JarLibDisplayTas jarlib-manifest=org.apache.tools.ant.taskdefs.optional.extension.JarLibManifestTask jarlib-available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask jarlib-resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask +setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy # deprecated ant tasks (kept for back compatibility) starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut diff --git a/src/main/org/apache/tools/ant/taskdefs/email/Message.java b/src/main/org/apache/tools/ant/taskdefs/email/Message.java index b39243884..0bc3dc8ce 100644 --- a/src/main/org/apache/tools/ant/taskdefs/email/Message.java +++ b/src/main/org/apache/tools/ant/taskdefs/email/Message.java @@ -53,6 +53,8 @@ */ package org.apache.tools.ant.taskdefs.email; +import org.apache.tools.ant.ProjectComponent; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -65,7 +67,7 @@ import java.io.PrintStream; * @author roxspring@yahoo.com Rob Oxspring * @since Ant 1.5 */ -public class Message { +public class Message extends ProjectComponent { private File messageSource = null; private StringBuffer buffer = new StringBuffer(); private String mimeType = "text/plain"; @@ -155,19 +157,19 @@ public class Message { String line = null; while ((line = in.readLine()) != null) { - out.println(line); + out.println(getProject().replaceProperties(line)); } } finally { freader.close(); } } else { - out.println(buffer); + out.println(getProject().replaceProperties(buffer.toString())); } } /** - * Returns true iff the mimeType has been set. + * Returns true if the mimeType has been set. * * @return false if the default value is in use */ diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java b/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java index 60030d6ff..187fc6159 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java @@ -310,9 +310,9 @@ public class EchoProperties extends Task { } return; } - + if (destfile.exists() && !destfile.canWrite()) { - String message = + String message = "Can not write to the specified destfile!"; if (failonerror) { throw new BuildException(message, location); @@ -333,7 +333,7 @@ public class EchoProperties extends Task { } finally { if (os != null) { try { - os.close(); + os.close(); } catch (IOException e) { } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java b/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java index d26702728..aef99650f 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java @@ -437,14 +437,16 @@ public class PropertyFile extends Task { newValue = currentValue; } else { int operationValue = 1; - try { - operationValue = fmt.parse(value).intValue(); - } catch (NumberFormatException nfe) { - // swallow - } catch (ParseException pe) { - // swallow + if (value != null) { + try { + operationValue = fmt.parse(value).intValue(); + } catch (NumberFormatException nfe) { + // swallow + } catch (ParseException pe) { + // swallow + } } - + if (operation == Operation.INCREMENT_OPER) { newValue = currentValue + operationValue; } else if (operation == Operation.DECREMENT_OPER) { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java index d8103a9ab..f0531ff4b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java @@ -186,7 +186,8 @@ public class ReplaceRegExp extends Task { public void setReplace(String replace) { if (subs != null) { - throw new BuildException("Only one substitution expression is allowed"); + throw new BuildException("Only one substitution expression is " + + "allowed"); } subs = new Substitution(); @@ -226,7 +227,8 @@ public class ReplaceRegExp extends Task { public Substitution createSubstitution() { if (subs != null) { - throw new BuildException("Only one substitution expression is allowed"); + throw new BuildException("Only one substitution expression is " + + "allowed"); } subs = new Substitution(); @@ -252,7 +254,7 @@ public class ReplaceRegExp extends Task { /** Perform the replace on the entire file */ protected void doReplace(File f, int options) throws IOException { - File parentDir = new File(new File(f.getAbsolutePath()).getParent()); + File parentDir = fileUtils.getParentFile(f); File temp = fileUtils.createTempFile("replace", ".txt", parentDir); FileReader r = null; @@ -268,12 +270,13 @@ public class ReplaceRegExp extends Task { boolean changes = false; - log("Replacing pattern '" + regex.getPattern(project) + "' with '" + subs.getExpression(project) + + 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); + Project.MSG_VERBOSE); if (byline) { LineNumberReader lnr = new LineNumberReader(br); @@ -318,10 +321,15 @@ public class ReplaceRegExp extends Task { w = null; if (changes) { - f.delete(); - temp.renameTo(f); - } else { - temp.delete(); + if (!f.delete()) { + throw new BuildException("Couldn't delete " + f, + getLocation()); + } + if (!temp.renameTo(f)) { + throw new BuildException("Couldn't rename temporary file " + + temp, getLocation()); + } + temp = null; } } finally { try { @@ -330,15 +338,16 @@ public class ReplaceRegExp extends Task { } } catch (Exception e) { } - ; try { if (w != null) { - r.close(); + w.close(); } } catch (Exception e) { } - ; + if (temp != null) { + temp.delete(); + } } } @@ -353,7 +362,8 @@ public class ReplaceRegExp extends Task { } if (file != null && filesets.size() > 0) { - throw new BuildException("You cannot supply the 'file' attribute and filesets at the same time."); + throw new BuildException("You cannot supply the 'file' attribute " + + "and filesets at the same time."); } int options = 0; @@ -378,12 +388,13 @@ public class ReplaceRegExp extends Task { try { doReplace(file, options); } catch (IOException e) { - log("An error occurred processing file: '" + file.getAbsolutePath() + "': " + e.toString(), + 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); + log("The following file is missing: '" + + file.getAbsolutePath() + "'", Project.MSG_ERR); } int sz = filesets.size(); @@ -395,18 +406,19 @@ public class ReplaceRegExp extends Task { String files[] = ds.getIncludedFiles(); for (int j = 0; j < files.length; j++) { - File f = new File(files[j]); + File f = new File(fs.getDir(getProject()), files[j]); if (f.exists()) { try { doReplace(f, options); } catch (Exception e) { - log("An error occurred processing file: '" + f.getAbsolutePath() + "': " + e.toString(), + 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); + log("The following file is missing: '" + + f.getAbsolutePath() + "'", Project.MSG_ERR); } } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Script.java b/src/main/org/apache/tools/ant/taskdefs/optional/Script.java index afe553307..e384fdbe1 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/Script.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/Script.java @@ -73,7 +73,17 @@ public class Script extends Task { private String language; private String script = ""; private Hashtable beans = new Hashtable(); - + + // Register BeanShell ourselves, since BSF does not + // natively support it (yet). + // This "hack" can be removed once BSF has been + // modified to support BeanShell or more dynamic + // registration. + static { + BSFManager.registerScriptingEngine( "beanshell", + "bsh.util.BeanShellBSFEngine", new String [] { "bsh" } ); + } + /** * Add a list of named objects to the list to be exported to the script */ diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java b/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java index 18c20a866..6875b9fbc 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java @@ -80,6 +80,7 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; +import javax.xml.transform.URIResolver; import javax.xml.transform.sax.SAXSource; @@ -108,7 +109,10 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware private XSLTLogger logger; /** possible resolver for publicIds */ - private EntityResolver resolver; + private EntityResolver entityResolver; + + /** possible resolver for URIs */ + private URIResolver uriResolver; public TraXLiaison() throws Exception { tfactory = TransformerFactory.newInstance(); @@ -145,12 +149,12 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware // FIXME: need to use a SAXSource as the source for the transform // so we can plug in our own entity resolver Source src = null; - if (resolver != null) { + if (entityResolver != null) { if (tfactory.getFeature(SAXSource.FEATURE)) { SAXParserFactory spFactory = SAXParserFactory.newInstance(); spFactory.setNamespaceAware(true); XMLReader reader = spFactory.newSAXParser().getXMLReader(); - reader.setEntityResolver(resolver); + reader.setEntityResolver(entityResolver); src = new SAXSource(reader, new InputSource(fis)); } else { throw new IllegalStateException("xcatalog specified, but " + @@ -164,6 +168,9 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware // not sure what could be the need of this... res.setSystemId(getSystemId(outfile)); + if (uriResolver != null) + transformer.setURIResolver(uriResolver); + transformer.transform(src, res); } finally { // make sure to close all handles, otherwise the garbage @@ -263,7 +270,13 @@ public class TraXLiaison implements XSLTLiaison, ErrorListener, XSLTLoggerAware /** Set the class to resolve entities during the transformation */ public void setEntityResolver(EntityResolver aResolver) throws Exception { - resolver = aResolver; + entityResolver = aResolver; + } + + /** Set the class to resolve URIs during the transformation + */ + public void setURIResolver(URIResolver aResolver) throws Exception { + uriResolver = aResolver; } } //-- TraXLiaison diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java index 7a0996a58..e9ec062b2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/CSharp.java @@ -261,17 +261,7 @@ public class CSharp "Accessibility.dll;" + "cscompmgd.dll;" + "CustomMarshalers.dll;" + - "IEExecRemote.dll;" + - "IEHost.dll;" + - "IIEHost.dll;" + - "ISymWrapper.dll;" + - "Microsoft.JScript.dll;" + - "Microsoft.VisualBasic.dll;" + - "Microsoft.VisualC.dll;" + - "Microsoft.Vsa.dll;" + "Mscorcfg.dll;" + - "office.dll;" + - "RegCode.dll;" + "System.Configuration.Install.dll;" + "System.Data.dll;" + "System.Design.dll;" + @@ -753,7 +743,8 @@ public class CSharp targetType.equals("module") || targetType.equals("winexe")) { targetType = targetType; } else { - throw new BuildException("targetType " + targetType + " is not a valid type"); + throw new BuildException("targetType " + targetType + + " is not one of 'exe', 'module', 'winexe' or 'library'" ); } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WsdlToDotnet.java b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WsdlToDotnet.java index 717b19cb7..043eb37f2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WsdlToDotnet.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/dotnet/WsdlToDotnet.java @@ -63,7 +63,7 @@ import java.io.File; * the framework SDK docos * @author Steve Loughran steve_l@iseran.com * @version 0.5 - * @ant.task name="csc" category="dotnet" + * @ant.task name="wsdltodotnet" category="dotnet" * @since ant 1.5 */ diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java index bc9839f42..14e1998a4 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java @@ -97,6 +97,9 @@ public class GenericDeploymentTool implements EJBDeploymentTool { /** The standard META-INF directory in jar files */ protected static final String META_DIR = "META-INF/"; + /** The standard MANIFEST file */ + protected static final String MANIFEST = META_DIR + "MANIFEST.MF"; + /** Name for EJB Deployment descriptor within EJB jars */ protected static final String EJB_DD = "ejb-jar.xml"; @@ -110,10 +113,10 @@ public class GenericDeploymentTool implements EJBDeploymentTool { /** The default analyzer */ public static final String DEFAULT_ANALYZER = ANALYZER_SUPER; - /** The analyzer class for the super analyzer */ + /** The analyzer class for the super analyzer */ public static final String ANALYZER_CLASS_SUPER = "org.apache.tools.ant.util.depend.bcel.AncestorAnalyzer"; - /** The analyzer class for the super analyzer */ + /** The analyzer class for the super analyzer */ public static final String ANALYZER_CLASS_FULL = "org.apache.tools.ant.util.depend.bcel.FullAnalyzer"; @@ -293,11 +296,11 @@ public class GenericDeploymentTool implements EJBDeploymentTool { if (analyzer == null) { analyzer = DEFAULT_ANALYZER; } - + if (analyzer.equals(ANALYZER_NONE)) { return; } - + String analyzerClassName = null; if (analyzer.equals(ANALYZER_SUPER)) { analyzerClassName = ANALYZER_CLASS_SUPER; @@ -306,10 +309,10 @@ public class GenericDeploymentTool implements EJBDeploymentTool { } else { analyzerClassName = analyzer; } - + try { Class analyzerClass = Class.forName(analyzerClassName); - dependencyAnalyzer + dependencyAnalyzer = (DependencyAnalyzer) analyzerClass.newInstance(); dependencyAnalyzer.addClassPath(new Path(task.getProject(), config.srcDir.getPath())); @@ -324,8 +327,8 @@ public class GenericDeploymentTool implements EJBDeploymentTool { Project.MSG_WARN); } } - - + + /** * Configure this tool for use in the ejbjar task. * @@ -429,6 +432,13 @@ public class GenericDeploymentTool implements EJBDeploymentTool { String ddPrefix = getVendorDDPrefix(baseName, descriptorFileName); + File manifestFile = getManifestFile(ddPrefix); + if (manifestFile != null) { + ejbFiles.put(MANIFEST, manifestFile); + } + + + // First the regular deployment descriptor ejbFiles.put(META_DIR + EJB_DD, new File(config.descriptorDir, descriptorFileName)); @@ -613,13 +623,13 @@ public class GenericDeploymentTool implements EJBDeploymentTool { if (endBaseName != -1) { baseName = descriptorFileName.substring(0, endBaseName); } else { - throw new BuildException("Unable to determine jar name " + throw new BuildException("Unable to determine jar name " + "from descriptor \"" + descriptorFileName + "\""); } } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) { File descriptorFile = new File(config.descriptorDir, descriptorFileName); String path = descriptorFile.getAbsolutePath(); - int lastSeparatorIndex + int lastSeparatorIndex = path.lastIndexOf(File.separator); if (lastSeparatorIndex == -1) { throw new BuildException("Unable to determine directory name holding descriptor"); @@ -698,14 +708,6 @@ public class GenericDeploymentTool implements EJBDeploymentTool { if (jarFile.exists()) { long lastBuild = jarFile.lastModified(); - if (config.manifest != null && config.manifest.exists() && - config.manifest.lastModified() > lastBuild) { - log("Build needed because manifest " + config.manifest + " is out of date", - Project.MSG_VERBOSE); - return true; - } - - Iterator fileIter = ejbFiles.values().iterator(); // Loop through the files seeing if any has been touched @@ -736,6 +738,30 @@ public class GenericDeploymentTool implements EJBDeploymentTool { } /** + * Get the manifets file to use for building the generic jar. + * + * If the file does not exist the global manifest from the config is used + * otherwise the default Ant manifest will be used. + * + * @param prefix the prefix where to llook for the manifest file based on + * the naming convention. + * + * @return the manifest file or null if the manifest file does not exist + */ + protected File getManifestFile(String prefix) { + File manifestFile + = new File(getConfig().descriptorDir, prefix + "manifest.mf"); + if (manifestFile.exists()) { + return manifestFile; + } + + if (config.manifest != null) { + return config.manifest; + } + return null; + } + + /** * Method used to encapsulate the writing of the JAR file. Iterates over the * filenames/java.io.Files in the Hashtable stored on the instance variable * ejbFiles. @@ -762,15 +788,9 @@ public class GenericDeploymentTool implements EJBDeploymentTool { InputStream in = null; Manifest manifest = null; try { - File manifestFile = new File(getConfig().descriptorDir, baseName + "-manifest.mf"); - if (manifestFile.exists()) { + File manifestFile = (File) files.get(MANIFEST); + if (manifestFile != null && manifestFile.exists()) { in = new FileInputStream(manifestFile); - } else if (config.manifest != null) { - in = new FileInputStream(config.manifest); - if (in == null) { - throw new BuildException("Could not find manifest file: " + config.manifest, - getLocation()); - } } else { String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf"; in = this.getClass().getResourceAsStream(defaultManifest); @@ -797,6 +817,10 @@ public class GenericDeploymentTool implements EJBDeploymentTool { // Loop through all the class files found and add them to the jar for (Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext();) { String entryName = (String) entryIterator.next(); + if (entryName.equals(MANIFEST)) { + continue; + } + File entryFile = (File) files.get(entryName); log("adding file '" + entryName + "'", @@ -855,7 +879,7 @@ public class GenericDeploymentTool implements EJBDeploymentTool { if (dependencyAnalyzer == null) { return; } - + dependencyAnalyzer.reset(); Iterator i = checkEntries.keySet().iterator(); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java index 5f388bce9..4068957ac 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java @@ -492,10 +492,14 @@ public class WeblogicDeploymentTool extends GenericDeploymentTool { javaTask.createArg().setLine(compiler); } } - - javaTask.createArg().setValue("-classpath"); - javaTask.createArg().setPath(getCombinedClasspath()); - + + Path combinedClasspath = getCombinedClasspath(); + if (combinedClasspath != null + && combinedClasspath.toString().trim().length() > 0) { + javaTask.createArg().setValue("-classpath"); + javaTask.createArg().setPath(combinedClasspath); + } + javaTask.createArg().setValue(sourceJar.getPath()); javaTask.createArg().setValue(destJar.getPath()); @@ -616,7 +620,7 @@ public class WeblogicDeploymentTool extends GenericDeploymentTool { } //Cycle Through generic and make sure its in weblogic - ClassLoader genericLoader + ClassLoader genericLoader = getClassLoaderFromJar(genericJarFile); for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) { @@ -711,7 +715,7 @@ public class WeblogicDeploymentTool extends GenericDeploymentTool { log("Weblogic Jar rebuild needed due to changed " + "interface or XML", Project.MSG_VERBOSE); } - + if (genericLoader instanceof AntClassLoader) { AntClassLoader loader = (AntClassLoader)genericLoader; loader.cleanup(); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java new file mode 100644 index 000000000..9f3560e5d --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java @@ -0,0 +1,98 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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.extension; + +/** + * Enum used in (@link Extension) to indicate the compatibility + * of one extension to another. See (@link Extension) for instances + * of object. + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * This file is from excalibur.extension package. Dont edit this file + * directly as there is no unit tests to make sure it is operational + * in ant. Edit file in excalibur and run tests there before changing + * ants file. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @version $Revision$ $Date$ + * @see Extension + */ +public final class Compatibility +{ + /** + * A string representaiton of compatibility level. + */ + private final String m_name; + + /** + * Create a compatibility enum with specified name. + * + * @param name the name of compatibility level + */ + Compatibility( final String name ) + { + m_name = name; + } + + /** + * Return name of compatibility level. + * + * @return the name of compatibility level + */ + public String toString() + { + return m_name; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java index cb7fd4aa2..7f0490c45 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java @@ -87,7 +87,8 @@ public final class Extension * Manifest Attribute Name object for EXTENSION_LIST. * @see Attributes.Name#EXTENSION_LIST */ - public static final Attributes.Name EXTENSION_LIST = Attributes.Name.EXTENSION_LIST; + public static final Attributes.Name EXTENSION_LIST = + new Attributes.Name( "Extension-List" );//Attributes.Name.EXTENSION_LIST; /** * <code>Name</code> object for <code>Optional-Extension-List</code> @@ -99,14 +100,15 @@ public final class Extension * @see <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/spec.html#dependnecy"> * Installed extension dependency</a> */ - public static final Attributes.Name OPTIONAL_EXTENSION_LIST = new Attributes.Name( "Optional-Extension-List" ); + public static final Attributes.Name OPTIONAL_EXTENSION_LIST = + new Attributes.Name( "Optional-Extension-List" ); /** * Manifest Attribute Name object for EXTENSION_NAME. * @see Attributes.Name#EXTENSION_NAME */ - public static final Attributes.Name EXTENSION_NAME = Attributes.Name.EXTENSION_NAME; - + public static final Attributes.Name EXTENSION_NAME = + new Attributes.Name( "Extension-Name" );//Attributes.Name.EXTENSION_NAME; /** * Manifest Attribute Name object for SPECIFICATION_VERSION. * @see Attributes.Name#SPECIFICATION_VERSION @@ -135,40 +137,42 @@ public final class Extension * Manifest Attribute Name object for IMPLEMENTATION_URL. * @see Attributes.Name#IMPLEMENTATION_URL */ - public static final Attributes.Name IMPLEMENTATION_URL = Attributes.Name.IMPLEMENTATION_URL; + public static final Attributes.Name IMPLEMENTATION_URL = + new Attributes.Name( "Implementation-URL" );//Attributes.Name.IMPLEMENTATION_URL; /** * Manifest Attribute Name object for IMPLEMENTATION_VENDOR_ID. * @see Attributes.Name#IMPLEMENTATION_VENDOR_ID */ - public static final Attributes.Name IMPLEMENTATION_VENDOR_ID = Attributes.Name.IMPLEMENTATION_VENDOR_ID; + public static final Attributes.Name IMPLEMENTATION_VENDOR_ID = + new Attributes.Name( "Implementation-Vendor-Id" );//Attributes.Name.IMPLEMENTATION_VENDOR_ID; /** * Enum indicating that extension is compatible with other extension. */ - public static final Compatability COMPATIBLE = - new Compatability( "COMPATIBLE" ); + public static final Compatibility COMPATIBLE = + new Compatibility( "COMPATIBLE" ); /** * Enum indicating that extension requires an upgrade * of specification to be compatible with other extension. */ - public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = - new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); + public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE = + new Compatibility( "REQUIRE_SPECIFICATION_UPGRADE" ); /** * Enum indicating that extension requires a vendor * switch to be compatible with other extension. */ - public static final Compatability REQUIRE_VENDOR_SWITCH = - new Compatability( "REQUIRE_VENDOR_SWITCH" ); + public static final Compatibility REQUIRE_VENDOR_SWITCH = + new Compatibility( "REQUIRE_VENDOR_SWITCH" ); /** * Enum indicating that extension requires an upgrade * of implementation to be compatible with other extension. */ - public static final Compatability REQUIRE_IMPLEMENTATION_UPGRADE = - new Compatability( "REQUIRE_IMPLEMENTATION_UPGRADE" ); + public static final Compatibility REQUIRE_IMPLEMENTATION_UPGRADE = + new Compatibility( "REQUIRE_IMPLEMENTATION_UPGRADE" ); /** * Enum indicating that extension is incompatible with @@ -176,8 +180,8 @@ public final class Extension * indicate). ie For example the other extension may have * a different ID. */ - public static final Compatability INCOMPATIBLE = - new Compatability( "INCOMPATIBLE" ); + public static final Compatibility INCOMPATIBLE = + new Compatibility( "INCOMPATIBLE" ); /** * The name of the optional package being made available, or required. @@ -499,10 +503,10 @@ public final class Extension * <code>Extension</code> with the specified <code>Extension</code>. * * @param required Description of the required optional package - * @return the enum indicating the compatability (or lack thereof) + * @return the enum indicating the compatibility (or lack thereof) * of specifed extension */ - public Compatability getCompatibilityWith( final Extension required ) + public Compatibility getCompatibilityWith( final Extension required ) { // Extension Name must match if( !m_extensionName.equals( required.getExtensionName() ) ) diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java index e9214b25c..d288f6ee2 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java @@ -61,6 +61,7 @@ import org.apache.tools.ant.Project; * Interface to locate a File that satisfies extension. * * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @author <a href="mailto:jeff@socialchange.net.au">Jeff Turner</> * @version $Revision$ $Date$ */ public interface ExtensionResolver diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java index d4845da6f..6c16665e8 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java @@ -61,12 +61,14 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.optional.extension.resolvers.LocationResolver; import org.apache.tools.ant.taskdefs.optional.extension.resolvers.URLResolver; +import org.apache.tools.ant.taskdefs.optional.extension.resolvers.AntResolver; /** * Try to locate a jar to satisfy an extension and place * location of jar into property. * * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @author <a href="mailto:jeff@socialchange.net.au">Jeff Turner</a> * @ant.task name="jarlib-resolver" */ public class JarLibResolveTask @@ -135,6 +137,11 @@ public class JarLibResolveTask m_resolvers.add( url ); } + public void addConfiguredAnt( final AntResolver ant ) + { + m_resolvers.add( ant ); + } + /** * Set the Extension looking for. * diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java index 0d277093f..97c339c21 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java @@ -123,29 +123,29 @@ public final class Specification * Enum indicating that extension is compatible with other Package * Specification. */ - public static final Compatability COMPATIBLE = - new Compatability( "COMPATIBLE" ); + public static final Compatibility COMPATIBLE = + new Compatibility( "COMPATIBLE" ); /** * Enum indicating that extension requires an upgrade * of specification to be compatible with other Package Specification. */ - public static final Compatability REQUIRE_SPECIFICATION_UPGRADE = - new Compatability( "REQUIRE_SPECIFICATION_UPGRADE" ); + public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE = + new Compatibility( "REQUIRE_SPECIFICATION_UPGRADE" ); /** * Enum indicating that extension requires a vendor * switch to be compatible with other Package Specification. */ - public static final Compatability REQUIRE_VENDOR_SWITCH = - new Compatability( "REQUIRE_VENDOR_SWITCH" ); + public static final Compatibility REQUIRE_VENDOR_SWITCH = + new Compatibility( "REQUIRE_VENDOR_SWITCH" ); /** * Enum indicating that extension requires an upgrade * of implementation to be compatible with other Package Specification. */ - public static final Compatability REQUIRE_IMPLEMENTATION_CHANGE = - new Compatability( "REQUIRE_IMPLEMENTATION_CHANGE" ); + public static final Compatibility REQUIRE_IMPLEMENTATION_CHANGE = + new Compatibility( "REQUIRE_IMPLEMENTATION_CHANGE" ); /** * Enum indicating that extension is incompatible with @@ -153,8 +153,8 @@ public final class Specification * indicate). ie For example the other Package Specification * may have a different ID. */ - public static final Compatability INCOMPATIBLE = - new Compatability( "INCOMPATIBLE" ); + public static final Compatibility INCOMPATIBLE = + new Compatibility( "INCOMPATIBLE" ); /** * The name of the Package Specification. @@ -395,10 +395,10 @@ public final class Specification * <code>Package Specification</code> with the specified <code>Extension</code>. * * @param other the other specification - * @return the enum indicating the compatability (or lack thereof) + * @return the enum indicating the compatibility (or lack thereof) * of specifed Package Specification */ - public Compatability getCompatibilityWith( final Specification other ) + public Compatibility getCompatibilityWith( final Specification other ) { // Specification Name must match if( !m_specificationTitle.equals( other.getSpecificationTitle() ) ) diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java new file mode 100644 index 000000000..ca30157a2 --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java @@ -0,0 +1,143 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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.extension.resolvers; + +import java.io.File; +import java.io.IOException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Ant; +import org.apache.tools.ant.taskdefs.optional.extension.Extension; +import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver; + +/** + * Resolver that just returns s specified location. + * + * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @author <a href="mailto:jeff@socialchange.net.au">Jeff Turner</> + * @version $Revision$ $Date$ + */ +public class AntResolver + implements ExtensionResolver +{ + private File m_antfile; + private File m_destfile; + private String m_target; + + public void setAntfile( File antfile ) + { + m_antfile = antfile; + } + + public void setDestfile( File destfile ) + { + m_destfile = destfile; + } + + public void setTarget( final String target ) + { + m_target = target; + } + + public File resolve( final Extension extension, + final Project project ) + throws BuildException + { + validate(); + + final Ant ant = (Ant)project.createTask( "ant" ); + ant.setInheritAll( false ); + ant.setAntfile( m_antfile.getName() ); + + try + { + final File dir = + m_antfile.getParentFile().getCanonicalFile(); + ant.setDir( dir ); + } + catch( final IOException ioe ) + { + throw new BuildException( ioe.getMessage(), ioe ); + } + + if( null != m_target ) + { + ant.setTarget( m_target ); + } + + ant.execute(); + + return m_destfile; + } + + private void validate() + { + if( null == m_antfile ) + { + final String message = "Must specify Buildfile"; + throw new BuildException( message ); + } + + if( null == m_destfile ) + { + final String message = "Must specify destination file"; + throw new BuildException( message ); + } + } + + public String toString() + { + return "Ant[" + m_antfile + "==>" + m_destfile + "]"; + } +} diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java index 119679d36..dbc30e120 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java @@ -63,6 +63,7 @@ import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver; * Resolver that just returns s specified location. * * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @author <a href="mailto:jeff@socialchange.net.au">Jeff Turner</> * @version $Revision$ $Date$ */ public class LocationResolver diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java index b3d204792..f4e1b8628 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java @@ -65,6 +65,7 @@ import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver; * Resolver that just returns s specified location. * * @author <a href="mailto:peter@apache.org">Peter Donald</a> + * @author <a href="mailto:jeff@socialchange.net.au">Jeff Turner</> * @version $Revision$ $Date$ */ public class URLResolver diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java b/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java index 9b125616e..6a5d26da3 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java @@ -74,7 +74,7 @@ import org.apache.tools.ant.taskdefs.MatchingTask; /** * Translates text embedded in files using Resource Bundle files. * - * @author <a href="mailto:umagesh@rediffmail.com">Magesh Umasankar</a> + * @author Magesh Umasankar */ public class Translate extends MatchingTask { @@ -228,8 +228,8 @@ public class Translate extends MatchingTask { } /** - * Whether or not to overwrite existing file irrespective of - * whether it is newer than the source file as well as the + * Whether or not to overwrite existing file irrespective of + * whether it is newer than the source file as well as the * resource bundle file. * Defaults to false. */ @@ -503,7 +503,8 @@ public class Translate extends MatchingTask { Project.MSG_DEBUG); } destLastModified = dest.lastModified(); - srcLastModified = new File(srcFiles[i]).lastModified(); + File src = fileUtils.resolveFile(ds.getBasedir(), srcFiles[j]); + srcLastModified = src.lastModified(); //Check to see if dest file has to be recreated if (forceOverwrite || destLastModified < srcLastModified @@ -517,10 +518,10 @@ public class Translate extends MatchingTask { log("Processing " + srcFiles[j], Project.MSG_DEBUG); FileOutputStream fos = new FileOutputStream(dest); - BufferedWriter out + BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos, destEncoding)); - FileInputStream fis = new FileInputStream(srcFiles[j]); - BufferedReader in + FileInputStream fis = new FileInputStream(src); + BufferedReader in = new BufferedReader(new InputStreamReader(fis, srcEncoding)); String line; while ((line = in.readLine()) != null) { diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java index 78668ed8c..df024f813 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java @@ -120,7 +120,7 @@ public class JspC extends MatchingTask { private String compilerName = "jasper"; /** - * -ieplugin <clsid>Java Plugin classid for Internet Explorer + * -ieplugin <clsid> Java Plugin classid for Internet Explorer */ private String iepluginid ; private boolean mapped ; @@ -134,25 +134,25 @@ public class JspC extends MatchingTask { protected boolean failOnError = true; /** - * -uribase <dir>The uri directory compilations should be relative to + * -uribase <dir> The uri directory compilations should be relative to * (Default is "/") */ private File uribase; /** - * -uriroot <dir>The root directory that uri files should be resolved + * -uriroot <dir> The root directory that uri files should be resolved * against, */ private File uriroot; /** - * -webinc <file>Creates partial servlet mappings for the -webapp option + * -webinc <file> Creates partial servlet mappings for the -webapp option */ private File webinc; /** - * -webxml <file>Creates a complete web.xml when using the -webapp option. + * -webxml <file> Creates a complete web.xml when using the -webapp option. */ private File webxml; @@ -298,7 +298,7 @@ public class JspC extends MatchingTask { } /** - * -webxml <file>Creates a complete web.xml when using the -webapp option. + * -webxml <file> Creates a complete web.xml when using the -webapp option. * * @param webxml The new Webxml value */ diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java index 2b11f7543..34a854e06 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java @@ -57,7 +57,7 @@ package org.apache.tools.ant.taskdefs.optional.jsp.compilers; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.optional.jsp.JspC; -import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.CommandlineJava; import java.util.Vector; import java.util.Enumeration; @@ -83,8 +83,8 @@ public abstract class DefaultJspCompilerAdapter */ protected void logAndAddFilesToCompile(JspC jspc, Vector compileList, - Commandline cmd) { - jspc.log("Compilation " + cmd.describeArguments(), + CommandlineJava cmd) { + jspc.log("Compilation " + cmd.describeJavaCommand(), Project.MSG_VERBOSE); StringBuffer niceSourceList = new StringBuffer("File"); @@ -130,7 +130,7 @@ public abstract class DefaultJspCompilerAdapter * * @param argument The argument */ - protected void addArg(Commandline cmd, String argument) { + protected void addArg(CommandlineJava cmd, String argument) { if (argument != null && argument.length() != 0) { cmd.createArgument().setValue(argument); } @@ -143,7 +143,7 @@ public abstract class DefaultJspCompilerAdapter * @param argument The argument * @param value the parameter */ - protected void addArg(Commandline cmd, String argument, String value) { + protected void addArg(CommandlineJava cmd, String argument, String value) { if (value != null) { cmd.createArgument().setValue(argument); cmd.createArgument().setValue(value); @@ -156,7 +156,7 @@ public abstract class DefaultJspCompilerAdapter * @param argument The argument * @param file the parameter */ - protected void addArg(Commandline cmd, String argument, File file) { + protected void addArg(CommandlineJava cmd, String argument, File file) { if (file != null) { cmd.createArgument().setValue(argument); cmd.createArgument().setFile(file); @@ -171,5 +171,13 @@ public abstract class DefaultJspCompilerAdapter public boolean implementsOwnDependencyChecking() { return false; } + + /** + * get our project + * @return owner project data + */ + public Project getProject() { + return getJspc().getProject(); + } } diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java index 78a233fd0..c6d1ca206 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java @@ -56,12 +56,13 @@ package org.apache.tools.ant.taskdefs.optional.jsp.compilers; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; -import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.CommandlineJava; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.taskdefs.optional.jsp.JspC; import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler; import org.apache.tools.ant.taskdefs.optional.jsp.JspNameMangler; import org.apache.tools.ant.taskdefs.Java; +import org.apache.tools.ant.taskdefs.ExecuteJava; import java.io.File; @@ -80,20 +81,41 @@ public class JasperC extends DefaultJspCompilerAdapter { public boolean execute() throws BuildException { getJspc().log("Using jasper compiler", Project.MSG_VERBOSE); - Commandline cmd = setupJasperCommand(); + CommandlineJava cmd = setupJasperCommand(); + /* + Path classpath=cmd.createClasspath(getProject()); + if (getJspc().getClasspath() != null) { + classpath=getJspc().getClasspath(); + } else { + classpath.concatSystemClasspath(); + } + ExecuteJava exec=new ExecuteJava(); + exec.execute(getProject()); + if ((err = executeJava()) != 0) { + if (failOnError) { + throw new BuildException("Java returned: " + err, location); + } else { + log("Java Result: " + err, Project.MSG_ERR); + } + */ + try { // Create an instance of the compiler, redirecting output to // the project log // REVISIT. ugly. - Java java = (Java) (getJspc().getProject()).createTask("java"); + Java java = (Java) (getProject().createTask("java")); if (getJspc().getClasspath() != null) { java.setClasspath(getJspc().getClasspath()); } else { - java.setClasspath(Path.systemClasspath); + Path classpath=new Path(getProject()); + classpath.concatSystemClasspath(); + java.setClasspath(classpath); } + java.setDir(getProject().getBaseDir()); java.setClassname("org.apache.jasper.JspC"); - String args[] = cmd.getArguments(); + //this is really irritating; we need a way to set stuff + String args[] = cmd.getJavaCommand().getArguments(); for (int i = 0; i < args.length; i++) { java.createArg().setValue(args[i]); } @@ -104,7 +126,6 @@ public class JasperC extends DefaultJspCompilerAdapter { java.execute(); return true; } catch (Exception ex) { - //@todo implement failonerror support here? if (ex instanceof BuildException) { throw (BuildException) ex; } else { @@ -122,8 +143,8 @@ public class JasperC extends DefaultJspCompilerAdapter { * build up a command line * @return a command line for jasper */ - private Commandline setupJasperCommand() { - Commandline cmd = new Commandline(); + private CommandlineJava setupJasperCommand() { + CommandlineJava cmd = new CommandlineJava(); JspC jspc = getJspc(); addArg(cmd, "-d", jspc.getDestdir()); addArg(cmd, "-p", jspc.getPackage()); diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java index 6d4f63c17..80fa156a7 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java @@ -611,17 +611,8 @@ public class FTP if (!dirCache.contains(dir)) { log("creating remote directory " + resolveFile(dir.getPath()), Project.MSG_VERBOSE); - ftp.makeDirectory(resolveFile(dir.getPath())); - // Both codes 550 and 553 can be produced by FTP Servers - // to indicate that an attempt to create a directory has - // failed because the directory already exists. - int result = ftp.getReplyCode(); - - if (!FTPReply.isPositiveCompletion(result) && - (result != 550) && (result != 553) && - !ignoreNoncriticalErrors) { - throw new BuildException("could not create directory: " + - ftp.getReplyString()); + if(!ftp.makeDirectory(resolveFile(dir.getPath()))) { + handleMkDirFailure(ftp); } dirCache.addElement(dir); } @@ -880,15 +871,7 @@ public class FTP // codes 521, 550 and 553 can be produced by FTP Servers // to indicate that an attempt to create a directory has // failed because the directory already exists. - - int rc = ftp.getReplyCode(); - - if (!(ignoreNoncriticalErrors - && (rc == 550 || rc == 553 || rc == 521))) { - throw new BuildException("could not create directory: " + - ftp.getReplyString()); - } - + handleMkDirFailure(ftp); if (verbose) { log("directory already exists"); } @@ -899,6 +882,21 @@ public class FTP } } + /** + * look at the response for a failed mkdir action, decide whether + * it matters or not. If it does, we throw an exception + * @param ftp current ftp connection + * @throws BuildException if this is an error to signal + */ + private void handleMkDirFailure(FTPClient ftp) + throws BuildException { + int rc=ftp.getReplyCode(); + if (!(ignoreNoncriticalErrors + && (rc == 550 || rc == 553 || rc == 521))) { + throw new BuildException("could not create directory: " + + ftp.getReplyString()); + } + } /** Runs the task. */ public void execute() diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java index 11528fded..d4f98d54b 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java @@ -62,11 +62,32 @@ import org.apache.tools.ant.*; import org.apache.tools.ant.util.JavaEnvUtils; /** - * proxy definition task. This allows all tasks in the build file - * executed after this task to access the web through a proxy server + * Sets Java's web proxy properties, so that tasks and code run in + * the same JVM can have through-the-firewall access to remote web sites, + * and remote ftp sites. + * You can nominate an http and ftp proxy, or a socks server, reset the server + * settings, or do nothing at all. + * <p> + * Examples + * <pre><setproxy/></pre> + * do nothing + * <pre><setproxy proxyhost="firewall"/></pre> + * set the proxy to firewall:80 + * <pre><setproxy proxyhost="firewall" proxyport="81"/></pre> + * set the proxy to firewall:81 + * <pre><setproxy proxyhost=""/></pre> + * stop using the http proxy; don't change the socks settings + * <pre><setproxy socksproxyhost="socksy"/></pre> + * use socks via socksy:1080 + * <pre><setproxy socksproxyhost=""/></pre> + * stop using the socks server + + + * @see <a href="http://java.sun.com/j2se/1.4/docs/guide/net/properties.html"> * java 1.4 network property list</a> * @author Steve Loughran + *@since Ant 1.5 * @ant.task */ public class SetProxy extends Task { @@ -98,7 +119,8 @@ public class SetProxy extends Task { private String nonProxyHosts = null; /** - * Set a proxy host. The port should be defined too. + * the HTTP/ftp proxy host. Set this to "" for the http proxy + * option to be disabled * * @param hostname the new proxy hostname */ @@ -108,7 +130,7 @@ public class SetProxy extends Task { /** - * set the proxy port number. + * the HTTP/ftp proxy port number; default is 80 * * @param port port number of the proxy */ @@ -117,7 +139,8 @@ public class SetProxy extends Task { } /** - * Set the SocksProxyHost attribute + * The name of a Socks server. Set to "" to turn socks + * proxying off. * * @param host The new SocksProxyHost value */ @@ -127,7 +150,7 @@ public class SetProxy extends Task { /** - * Set the SocksProxyPort attribute + * Set the ProxyPort for socks connections. The default value is 1080 * * @param port The new SocksProxyPort value */ @@ -136,8 +159,9 @@ public class SetProxy extends Task { } /** - * Specify a list of hosts to bypass the proxy on. These should be separated - * with the vertical bar character '|'. + * A list of hosts to bypass the proxy on. These should be separated + * with the vertical bar character '|'. Only in Java 1.4 does ftp use + * this list. * e.g. fozbot.corp.sun.com|*.eng.sun.com * @param nonProxyHosts lists of hosts to talk direct to */ diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java index c702262ca..6204afc19 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java @@ -327,7 +327,9 @@ public class TelnetTask extends Task { Thread.sleep(250); } if (is.available() == 0) { - throw new BuildException("Response Timed-Out", getLocation()); + throw new BuildException( + "Response timed-out waiting for \""+s+'\"', + getLocation()); } sb.append((char) is.read()); } diff --git a/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java b/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java index 0b5f71f94..2f06f3850 100644 --- a/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java +++ b/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java @@ -116,7 +116,7 @@ public abstract class DefaultRmicAdapter implements RmicAdapter { * <li>for JRMP it will return *_getStubClassSuffix (and * *_getSkelClassSuffix if JDK 1.1 is used)</li> * - * <li>for IDL it will return a random name, causing <rmic> to + * <li>for IDL it will return a random name, causing <rmic> to * always recompile.</li> * * <li>for IIOP it will return _*_getStubClassSuffix for diff --git a/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/src/main/org/apache/tools/ant/types/AbstractFileSet.java index 00b4a4bb6..31af72392 100644 --- a/src/main/org/apache/tools/ant/types/AbstractFileSet.java +++ b/src/main/org/apache/tools/ant/types/AbstractFileSet.java @@ -89,7 +89,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, private File dir; private boolean useDefaultExcludes = true; private boolean isCaseSensitive = true; - + private boolean followSymlinks = true; public AbstractFileSet() { super(); @@ -101,6 +101,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, this.additionalPatterns = fileset.additionalPatterns; this.useDefaultExcludes = fileset.useDefaultExcludes; this.isCaseSensitive = fileset.isCaseSensitive; + this.followSymlinks = fileset.followSymlinks; setProject(fileset.getProject()); } @@ -111,12 +112,15 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, * this element if you make it a reference.</p> */ public void setRefid(Reference r) throws BuildException { - if (dir != null || defaultPatterns.hasPatterns()) { + if (dir != null || defaultPatterns.hasPatterns(getProject())) { throw tooManyAttributes(); } if (!additionalPatterns.isEmpty()) { throw noChildrenAllowed(); } + if (!selectors.isEmpty()) { + throw noChildrenAllowed(); + } super.setRefid(r); } @@ -276,7 +280,14 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, this.isCaseSensitive = isCaseSensitive; } - + /** + * Sets whether or not symbolic links should be followed. + * + * @param followSymlinks whether or not symbolic links should be followed + */ + public void setFollowSymlinks(boolean followSymlinks) { + this.followSymlinks = followSymlinks; + } /** * sets the name used for this datatype instance. @@ -327,6 +338,7 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, DirectoryScanner ds = new DirectoryScanner(); setupDirectoryScanner(ds, p); + ds.setFollowSymlinks(followSymlinks); ds.scan(); return ds; } @@ -393,6 +405,27 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, } /** + * Indicates whether there are any patterns here. + * + * @return whether any patterns are in this container + */ + public boolean hasPatterns() { + if (defaultPatterns.hasPatterns(getProject())) { + return true; + } + + Enumeration enum = additionalPatterns.elements(); + while (enum.hasMoreElements()) { + PatternSet ps = (PatternSet) enum.nextElement(); + if (ps.hasPatterns(getProject())) { + return true; + } + } + + return false; + } + + /** * Gives the count of the number of selectors in this container * * @return the number of selectors in this container @@ -437,7 +470,14 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, selectors.addElement(selector); } - /* Methods below all implement the static selectors */ + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public void addSelector(SelectSelector selector) { + appendSelector(selector); + } /** * add an "And" selector entry on the selector list @@ -477,56 +517,56 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, /** * add a selector date entry on the selector list */ - public void addDateselect(DateSelector selector) { + public void addDate(DateSelector selector) { appendSelector(selector); } /** * add a selector size entry on the selector list */ - public void addSizeselect(SizeSelector selector) { + public void addSize(SizeSelector selector) { appendSelector(selector); } /** * add a selector filename entry on the selector list */ - public void addFilenameselect(FilenameSelector selector) { + public void addFilename(FilenameSelector selector) { appendSelector(selector); } /** * add an extended selector entry on the selector list */ - public void addExtendSelect(ExtendSelector selector) { + public void addCustom(ExtendSelector selector) { appendSelector(selector); } /** * add a contains selector entry on the selector list */ - public void addContainsSelect(ContainsSelector selector) { + public void addContains(ContainsSelector selector) { appendSelector(selector); } /** * add a present selector entry on the selector list */ - public void addPresentSelect(PresentSelector selector) { + public void addPresent(PresentSelector selector) { appendSelector(selector); } /** * add a depth selector entry on the selector list */ - public void addDepthSelect(DepthSelector selector) { + public void addDepth(DepthSelector selector) { appendSelector(selector); } /** * add a depends selector entry on the selector list */ - public void addDependSelect(DependSelector selector) { + public void addDepend(DependSelector selector) { appendSelector(selector); } diff --git a/src/main/org/apache/tools/ant/types/Commandline.java b/src/main/org/apache/tools/ant/types/Commandline.java index e19b9e985..23eeab308 100644 --- a/src/main/org/apache/tools/ant/types/Commandline.java +++ b/src/main/org/apache/tools/ant/types/Commandline.java @@ -488,7 +488,7 @@ public class Commandline implements Cloneable { /** * Returns a String that describes the command and arguments * suitable for verbose output before a call to - * <code>Runtime.exec(String[])<code> + * <code>Runtime.exec(String[])<code>. * * <p>This method assumes that the first entry in the array is the * executable to run.</p> diff --git a/src/main/org/apache/tools/ant/types/CommandlineJava.java b/src/main/org/apache/tools/ant/types/CommandlineJava.java index 12e5bc337..8ea71bf7e 100644 --- a/src/main/org/apache/tools/ant/types/CommandlineJava.java +++ b/src/main/org/apache/tools/ant/types/CommandlineJava.java @@ -72,8 +72,17 @@ import org.apache.tools.ant.util.JavaEnvUtils; */ public class CommandlineJava implements Cloneable { + /** + * commands to the JVM + */ private Commandline vmCommand = new Commandline(); + /** + * actual java commands + */ private Commandline javaCommand = new Commandline(); + /** + * properties to add using -D + */ private SysProperties sysProperties = new SysProperties(); private Path classpath = null; private String vmVersion; @@ -151,6 +160,9 @@ public class CommandlineJava implements Cloneable { } + /** + * constructor uses the VM we are running on now. + */ public CommandlineJava() { setVm(JavaEnvUtils.getJreExecutable("java")); setVmversion(JavaEnvUtils.getJavaVersion()); @@ -178,7 +190,7 @@ public class CommandlineJava implements Cloneable { /** * set a jar file to execute via the -jar option. - * @param the pathname of the jar to execute + * @param jarpathname the pathname of the jar to execute */ public void setJar(String jarpathname){ javaCommand.setExecutable(jarpathname); @@ -272,6 +284,7 @@ public class CommandlineJava implements Cloneable { } /** + * Specify max memory of the JVM * -mx or -Xmx depending on VM version */ public void setMaxmemory(String max){ @@ -279,6 +292,10 @@ public class CommandlineJava implements Cloneable { } + /** + * get a string description + * @return the command line as a string + */ public String toString() { return Commandline.toString(getCommandline()); } @@ -361,6 +378,10 @@ public class CommandlineJava implements Cloneable { return sysProperties; } + /** + * clone the object; do a deep clone of all fields in the class + * @return a CommandlineJava object + */ public Object clone() { CommandlineJava c = new CommandlineJava(); c.vmCommand = (Commandline) vmCommand.clone(); diff --git a/src/main/org/apache/tools/ant/types/Path.java b/src/main/org/apache/tools/ant/types/Path.java index 97cc61e17..3d528d263 100644 --- a/src/main/org/apache/tools/ant/types/Path.java +++ b/src/main/org/apache/tools/ant/types/Path.java @@ -240,7 +240,7 @@ public class Path extends DataType implements Cloneable { */ public void append(Path other) { if (other == null) { - return; + return; } String[] l = other.list(); for (int i = 0; i < l.length; i++) { diff --git a/src/main/org/apache/tools/ant/types/PatternSet.java b/src/main/org/apache/tools/ant/types/PatternSet.java index d5d0d2a16..e223aeef9 100644 --- a/src/main/org/apache/tools/ant/types/PatternSet.java +++ b/src/main/org/apache/tools/ant/types/PatternSet.java @@ -382,9 +382,13 @@ public class PatternSet extends DataType { /** * helper for FileSet. */ - boolean hasPatterns() { - return includesFileList.size() > 0 || excludesFileList.size() > 0 - || includeList.size() > 0 || excludeList.size() > 0; + boolean hasPatterns(Project p) { + if (isReference()) { + return getRef(p).hasPatterns(p); + } else { + return includesFileList.size() > 0 || excludesFileList.size() > 0 + || includeList.size() > 0 || excludeList.size() > 0; + } } /** diff --git a/src/main/org/apache/tools/ant/types/XMLCatalog.java b/src/main/org/apache/tools/ant/types/XMLCatalog.java index c03f3d64d..cb996ae24 100644 --- a/src/main/org/apache/tools/ant/types/XMLCatalog.java +++ b/src/main/org/apache/tools/ant/types/XMLCatalog.java @@ -58,57 +58,111 @@ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; +import java.io.FileNotFoundException; import java.net.URL; +import java.net.MalformedURLException; import java.util.Enumeration; +import java.util.Stack; import java.util.Vector; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.sax.SAXSource; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.ParserConfigurationException; + import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.AntClassLoader; +import org.apache.tools.ant.util.FileUtils; + import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; -import org.apache.tools.ant.util.LoaderUtils; -import org.apache.tools.ant.util.FileUtils; +import org.xml.sax.XMLReader; + + /** - * This data type provides a catalog of DTD locations. - * <p> + * <p>This data type provides a catalog of resource locations (such as + * DTDs and XML entities), based on the <a + * href="http://oasis-open.org/committees/entity/spec-2001-08-06.html"> + * OASIS "Open Catalog" standard</a>. The catalog entries are used + * both for Entity resolution and URI resolution, in accordance with + * the {@link org.xml.sax.EntityResolver EntityResolver} and {@link + * javax.xml.transform.URIResolver URIResolver} interfaces as defined + * in the <a href="http://java.sun.com/xml/jaxp">Java API for XML + * Processing Specification</a>.</p> + * + * <p>Currently, only <code><dtd></code> and + * <code><entity></code> elements may be specified inline; these + * correspond to OASIS catalog entry types <code>PUBLIC</code> and + * <code>URI</code> respectively.</p> + * + * <p>The following is a usage example:</p> + * * <code> - * <catalog><br> + * <xmlcatalog><br> * <dtd publicId="" location="/path/to/file.jar" /><br> - * <dtd publicId location="/path/to/file2.jar" /gt;<br> + * <dtd publicId="" location="/path/to/file2.jar" /><br> * <entity publicId="" location="/path/to/file3.jar" /><br> * <entity publicId="" location="/path/to/file4.jar" /><br> - * </catalog><br> + * </xmlcatalog><br> * </code> * <p> * The object implemention <code>sometask</code> must provide a method called - * <code>createCatalog</code> which returns an instance of + * <code>createXMLCatalog</code> which returns an instance of * <code>XMLCatalog</code>. Nested DTD and entity definitions are handled by * the XMLCatalog object and must be labeled <code>dtd</code> and * <code>entity</code> respectively.</p> * - * <p>Possible future extension could allow a catalog file instead of nested - * elements, or use Norman Walsh's entity resolver from xml-commons</p> + * <p>The following is a description of the resolution algorithm: + * entities/URIs/dtds are looked up in each of the following contexts, + * stopping when a valid and readable resource is found: + * <ol> + * <li>In the local filesystem</li> + * <li>In the classpath</li> + * <li>In URL-space</li> + * </ol> + * </p> + * + * <p>See {@link + * org.apache.tools.ant.taskdefs.optional.XMLValidateTask + * XMLValidateTask} for an example of a task that has integrated + * support for XMLCatalogs.</p> + * + * <p>Possible future extension could provide for additional OASIS + * entry types to be specified inline, and external catalog files + * using the xml-commons resolver library</p> * * @author dIon Gillard * @author Erik Hatcher + * @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> * @version $Id$ */ -public class XMLCatalog extends DataType implements Cloneable, EntityResolver { +public class XMLCatalog extends DataType implements Cloneable, EntityResolver, URIResolver { /** File utilities instance */ private FileUtils fileUtils = FileUtils.newFileUtils(); - + //-- Fields ---------------------------------------------------------------- - + /** holds dtd/entity objects until needed */ private Vector elements = new Vector(); + /** + * Classpath in which to attempt to resolve resources. + */ private Path classpath; //-- Methods --------------------------------------------------------------- - + + public XMLCatalog() { + checked = false; + } + /** + * Returns the elements of the catalog - DTDLocation objects. + * * @return the elements of the catalog - DTDLocation objects */ private Vector getElements() { @@ -116,6 +170,8 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } /** + * Returns the classpath in which to attempt to resolve resources. + * * @return the classpath */ private Path getClasspath() { @@ -123,25 +179,22 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } /** - * Set the list of DTDLocation object sin the catalog + * Set the list of DTDLocation objects in the catalog. Not + * allowed if this catalog is itself a reference to another + * catalog -- that is, a catalog cannot both refer to another + * <em>and</em> contain elements or other attributes. * * @param aVector the new list of DTD Locations to use in the catalog. */ private void setElements(Vector aVector) { elements = aVector; } - - /** - * Add a DTD Location to the catalog - * - * @param aDTD the DTDLocation instance to be aded to the catalog - */ - private void addElement(DTDLocation aDTD) { - getElements().addElement(aDTD); - } /** - * Allows nested classpath elements + * Allows nested classpath elements. Not allowed if this catalog + * is itself a reference to another catalog -- that is, a catalog + * cannot both refer to another <em>and</em> contain elements or + * other attributes. */ public Path createClasspath() { if (isReference()) { @@ -150,11 +203,15 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { if (this.classpath == null) { this.classpath = new Path(getProject()); } + checked = false; return this.classpath.createPath(); } /** - * Allows simple classpath string + * Allows simple classpath string. Not allowed if this catalog is + * itself a reference to another catalog -- that is, a catalog + * cannot both refer to another <em>and</em> contain elements or + * other attributes. */ public void setClasspath(Path classpath) { if (isReference()) { @@ -165,23 +222,32 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } else { this.classpath.append(classpath); } + checked = false; } /** - * Allows classpath reference + * Allows classpath reference. Not allowed if this catalog is + * itself a reference to another catalog -- that is, a catalog + * cannot both refer to another <em>and</em> contain elements or + * other attributes. */ public void setClasspathRef(Reference r) { if (isReference()) { throw tooManyAttributes(); } createClasspath().setRefid(r); + checked = false; } /** - * Creates the nested <code><dtd></code> element. + * Creates the nested <code><dtd></code> element. Not + * allowed if this catalog is itself a reference to another + * catalog -- that is, a catalog cannot both refer to another + * <em>and</em> contain elements or other attributes. * - * @param dtd the infromation about the DTD to be added to the catalog - * @exception BuildException if this is a reference and no nested + * @param dtd the information about the PUBLIC resource mapping to + * be added to the catalog + * @exception BuildException if this is a reference and no nested * elements are allowed. */ public void addDTD(DTDLocation dtd) throws BuildException { @@ -190,13 +256,18 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } getElements().addElement(dtd); + checked = false; } - + /** - * Creates the nested <code><entity></code> element + * Creates the nested <code><entity></code> element. Not + * allowed if this catalog is itself a reference to another + * catalog -- that is, a catalog cannot both refer to another + * <em>and</em> contain elements or other attributes. * - * @param dtd the infromation about the DTD to be added to the catalog - * @exception BuildException if this is a reference and no nested + * @param dtd the information about the URI resource mapping to be + * added to the catalog + * @exception BuildException if this is a reference and no nested * elements are allowed. */ public void addEntity(DTDLocation dtd) throws BuildException { @@ -204,7 +275,10 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } /** - * Loads a nested XMLCatalog into our definition + * Loads a nested <code><xmlcatalog></code> into our + * definition. Not allowed if this catalog is itself a reference + * to another catalog -- that is, a catalog cannot both refer to + * another <em>and</em> contain elements or other attributes. * * @param catalog Nested XMLCatalog */ @@ -224,15 +298,19 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { // Append the classpath of the nested catalog Path nestedClasspath = catalog.getClasspath(); createClasspath().append(nestedClasspath); + checked = false; } /** - * Makes this instance in effect a reference to another XCatalog instance. + * Makes this instance in effect a reference to another XMLCatalog + * instance. * * <p>You must not set another attribute or nest elements inside - * this element if you make it a reference.</p> + * this element if you make it a reference. That is, a catalog + * cannot both refer to another <em>and</em> contain elements or + * attributes.</p> * - * @param r the reference to which this catalogi instance is associated + * @param r the reference to which this catalog instance is associated * @exception BuildException if this instance already has been configured. */ public void setRefid(Reference r) throws BuildException { @@ -241,7 +319,7 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } // change this to get the objects from the other reference Object o = r.getReferencedObject(getProject()); - // we only support references to other XCatalogs + // we only support references to other XMLCatalogs if (o instanceof XMLCatalog) { // set all elements from referenced catalog to this one XMLCatalog catalog = (XMLCatalog) o; @@ -250,81 +328,81 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { String msg = r.getRefId() + " does not refer to an XMLCatalog"; throw new BuildException(msg); } - super.setRefid(r); } /** + * Implements the EntityResolver.resolveEntity() interface method. + * * @see org.xml.sax.EntityResolver#resolveEntity */ public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { - InputSource source = null; - DTDLocation matchingDTD = findMatchingDTD(publicId); - if (matchingDTD != null) { - // check if publicId is mapped to a file - log("Matching DTD found for publicId: '" + publicId + - "' location: '" + matchingDTD.getLocation() + "'", - Project.MSG_DEBUG); - File dtdFile = project.resolveFile(matchingDTD.getLocation()); - if (dtdFile.exists() && dtdFile.canRead()) { - source = new InputSource(new FileInputStream(dtdFile)); - URL dtdFileURL = fileUtils.getFileURL(dtdFile); - source.setSystemId(dtdFileURL.toExternalForm()); - log("matched a readable file", Project.MSG_DEBUG); - } else { - // check if publicId is a resource - - AntClassLoader loader = null; - if (classpath != null) { - loader = new AntClassLoader(project, classpath); - } else { - loader = new AntClassLoader(project, Path.systemClasspath); - } - InputStream is - = loader.getResourceAsStream(matchingDTD.getLocation()); - if (is != null) { - source = new InputSource(is); - source.setSystemId(loader.getResource( - matchingDTD.getLocation()).toExternalForm()); - log("matched a resource", Project.MSG_DEBUG); - } else { - // check if it's a URL - try { - URL dtdUrl = new URL(matchingDTD.getLocation()); - InputStream dtdIs = dtdUrl.openStream(); - if (dtdIs != null) { - source = new InputSource(dtdIs); - source.setSystemId(dtdUrl.toExternalForm()); - log("matched as a URL", Project.MSG_DEBUG); - } else { - log("No match, parser will use: '" + systemId + "'", - Project.MSG_DEBUG); - } - } catch (IOException ioe) { - //ignore - } - } - } - } else { - log("No match, parser will use: '" + systemId + "'", - Project.MSG_DEBUG); + if (!checked) { + // make sure we don't have a circular reference here + Stack stk = new Stack(); + stk.push(this); + dieOnCircularReference(stk, getProject()); + } + + log("resolveEntity: '" + publicId + "': '" + systemId + "'", + Project.MSG_DEBUG); + + InputSource inputSource = resolveEntityImpl(publicId, systemId); + + if (inputSource == null) { + log("No matching catalog entry found, parser will use: '" + + systemId + "'", Project.MSG_DEBUG); } - // else let the parser handle it as a URI as we don't know what to - // do with it + + return inputSource; + } + + /** + * Implements the URIResolver.resolve() interface method. + * + * @see javax.xml.transform.URIResolver#resolve + */ + public Source resolve(String href, String base) + throws TransformerException { + + if (!checked) { + // make sure we don't have a circular reference here + Stack stk = new Stack(); + stk.push(this); + dieOnCircularReference(stk, getProject()); + } + + SAXSource source = null; + InputSource inputSource = null; + + String uri = removeFragment(href); + + log("resolve: '" + uri + "' with base: '" + base + "'", Project.MSG_DEBUG); + + source = resolveImpl(uri, base); + + if (source == null) { + log("No matching catalog entry found, parser will use: '" + + href + "'", Project.MSG_DEBUG); + } + else { + setEntityResolver(source); + } + return source; } - + /** * Find a DTDLocation instance for the given publicId. * - * @param publicId the publicId of the DTD for which local information is - * required - * @return a DTDLocation instance with information on the local location - * of the DTD or null if no such information is available + * @param publicId the publicId of the Resource for which local information + * is required + * @return a DTDLocation instance with information on the local location + * of the Resource or null if no such information is available */ - private DTDLocation findMatchingDTD(String publicId) { + private DTDLocation findMatchingEntry(String publicId) { Enumeration elements = getElements().elements(); DTDLocation element = null; while (elements.hasMoreElements()) { @@ -335,6 +413,246 @@ public class XMLCatalog extends DataType implements Cloneable, EntityResolver { } return null; } - -} + /** + * <p>This is called from the URIResolver to set an EntityResolver + * on the SAX parser to be used for new XML documents that are + * encountered as a result of the document() function, xsl:import, + * or xsl:include. This is done because the XSLT processor calls + * out to the SAXParserFactory itself to create a new SAXParser to + * parse the new document. The new parser does not automatically + * inherit the EntityResolver of the original (although arguably + * it should). See below:</p> + * + * <tt>"If an application wants to set the ErrorHandler or + * EntityResolver for an XMLReader used during a transformation, + * it should use a URIResolver to return the SAXSource which + * provides (with getXMLReader) a reference to the XMLReader"</tt> + * + * <p>...quoted from page 118 of the Java API for XML + * Processing 1.1 specification</p> + * + */ + private void setEntityResolver(SAXSource source) throws TransformerException { + + XMLReader reader = source.getXMLReader(); + if (reader == null) { + SAXParserFactory spFactory = SAXParserFactory.newInstance(); + spFactory.setNamespaceAware(true); + try { + reader = spFactory.newSAXParser().getXMLReader(); + } + catch (ParserConfigurationException ex) { + throw new TransformerException(ex); + } + catch (SAXException ex) { + throw new TransformerException(ex); + } + } + reader.setEntityResolver(this); + source.setXMLReader(reader); + } + + /** + * Utility method to remove trailing fragment from a URI. + * For example, + * <code>http://java.sun.com/index.html#chapter1</code> + * would return <code>http://java.sun.com/index.html</code>. + * + * @param uri The URI to process. It may or may not contain a + * fragment. + * @return The URI sans fragment. + */ + private String removeFragment(String uri) { + String result = uri; + String fragment = null; + int hashPos = uri.indexOf("#"); + if (hashPos >= 0) { + result = uri.substring(0, hashPos); + fragment = uri.substring(hashPos+1); + } + return result; + } + + /** + * Utility method to lookup a DTDLocation in the filesystem. + * + * @return An InputSource for reading the file, or <code>null</code> + * if the file does not exist or is not readable. + */ + private InputSource filesystemLookup(DTDLocation matchingEntry) { + + String uri = matchingEntry.getLocation(); + File basedir = null; + + // + // The DTDLocation may specify a relative path for its + // location attribute. This is resolved using the appropriate + // base. + // + File resFile = project.resolveFile(uri); + InputSource source = null; + + if (resFile.exists() && resFile.canRead()) { + try { + source = new InputSource(new FileInputStream(resFile)); + URL resFileURL = fileUtils.getFileURL(resFile); + String sysid = resFileURL.toExternalForm(); + source.setSystemId(sysid); + log("catalog entry matched a readable file: '" + + sysid + "'", Project.MSG_DEBUG); + } catch(FileNotFoundException ex) { + // ignore + } catch(MalformedURLException ex) { + // ignore + } catch(IOException ex) { + // ignore + } + } + + return source; + } + + /** + * Utility method to lookup a DTDLocation in the classpath. + * + * @return An InputSource for reading the resource, or <code>null</code> + * if the resource does not exist in the classpath or is not readable. + */ + private InputSource classpathLookup(DTDLocation matchingEntry) { + + InputSource source = null; + + AntClassLoader loader = null; + if (classpath != null) { + loader = new AntClassLoader(project, classpath); + } else { + loader = new AntClassLoader(project, Path.systemClasspath); + } + + // + // for classpath lookup we ignore the base directory + // + InputStream is + = loader.getResourceAsStream(matchingEntry.getLocation()); + + if (is != null) { + source = new InputSource(is); + URL entryURL = loader.getResource(matchingEntry.getLocation()); + String sysid = entryURL.toExternalForm(); + source.setSystemId(sysid); + log("catalog entry matched a resource in the classpath: '" + + sysid + "'", Project.MSG_DEBUG); + } + + return source; + } + + /** + * Utility method to lookup a DTDLocation in URL-space. + * + * @return An InputSource for reading the resource, or <code>null</code> + * if the resource does not identify a valid URL or is not readable. + */ + private InputSource urlLookup(String uri, String base) { + + InputSource source = null; + URL url = null; + + try { + if (base == null) { + url = new URL(uri); + } + else { + URL baseURL = new URL(base); + url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri)); + } + } + catch (MalformedURLException ex) { + // ignore + } + + if (url != null) { + try { + InputStream is = url.openStream(); + if (is != null) { + source = new InputSource(is); + String sysid = url.toExternalForm(); + source.setSystemId(sysid); + log("catalog entry matched as a URL: '" + + sysid + "'", Project.MSG_DEBUG); + } + } catch(IOException ex) { + // ignore + } + } + + return source; + + } + + /** + * Implements the guts of the resolveEntity() lookup strategy. + */ + private InputSource resolveEntityImpl(String publicId, + String systemId) { + + InputSource result = null; + + DTDLocation matchingEntry = findMatchingEntry(publicId); + + if (matchingEntry != null) { + + log("Matching catalog entry found for publicId: '" + + matchingEntry.getPublicId() + "' location: '" + + matchingEntry.getLocation() + "'", + Project.MSG_DEBUG); + + result = filesystemLookup(matchingEntry); + + if (result == null) { + result = classpathLookup(matchingEntry); + } + + if (result == null) { + result = urlLookup(matchingEntry.getLocation(), null); + } + } + return result; + } + + /** + * Implements the guts of the resolve() lookup strategy. + */ + private SAXSource resolveImpl(String href, String base) + throws TransformerException { + + SAXSource result = null; + InputSource source = null; + + DTDLocation matchingEntry = findMatchingEntry(href); + + if (matchingEntry != null) { + + log("Matching catalog entry found for uri: '" + + matchingEntry.getPublicId() + "' location: '" + + matchingEntry.getLocation() + "'", + Project.MSG_DEBUG); + + source = filesystemLookup(matchingEntry); + + if (source == null) { + source = classpathLookup(matchingEntry); + } + + if (source == null) { + source = urlLookup(matchingEntry.getLocation(), base); + } + + if (source != null) { + result = new SAXSource(source); + } + } + return result; + } +} diff --git a/src/main/org/apache/tools/ant/types/defaults.properties b/src/main/org/apache/tools/ant/types/defaults.properties index fbaed1781..10b34082a 100644 --- a/src/main/org/apache/tools/ant/types/defaults.properties +++ b/src/main/org/apache/tools/ant/types/defaults.properties @@ -14,4 +14,5 @@ substitution=org.apache.tools.ant.types.Substitution xmlcatalog=org.apache.tools.ant.types.XMLCatalog extensionSet=org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet extension=org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter -libfileset=org.apache.tools.ant.taskdefs.optional.extension.LibFileSet
\ No newline at end of file +libfileset=org.apache.tools.ant.taskdefs.optional.extension.LibFileSet +selector=org.apache.tools.ant.types.selectors.SelectSelector diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java index 73095f8d3..c155130ac 100644 --- a/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java @@ -83,7 +83,7 @@ public abstract class BaseExtendSelector extends BaseSelector implements } /** - * Set all the Parameters for this dynamic selector, collected by + * Set all the Parameters for this custom selector, collected by * the ExtendSelector class. * * @param parameters the complete set of parameters for this selector @@ -94,7 +94,7 @@ public abstract class BaseExtendSelector extends BaseSelector implements /** * Allows access to the parameters gathered and set within the - * <extendselect> tag. + * <custom> tag. * * @return the set of parameters defined for this selector */ diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java index b1e0a0f3f..a69b799ce 100644 --- a/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java @@ -118,7 +118,9 @@ public abstract class BaseSelector extends DataType implements FileSelector { * in isSelected() in the case of an error condition. */ public void validate() { - verifySettings(); + if (getError() == null) { + verifySettings(); + } if (getError() != null) { throw new BuildException(errmsg); } diff --git a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java index ac3a97f6c..a783a7999 100644 --- a/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java +++ b/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java @@ -98,13 +98,9 @@ public abstract class BaseSelectorContainer extends BaseSelector * Returns the set of selectors as an array. */ public FileSelector[] getSelectors(Project p) { - if (isReference()) { - return getRef(p).getSelectors(p); - } else { - FileSelector[] result = new FileSelector[selectorsList.size()]; - selectorsList.copyInto(result); - return result; - } + FileSelector[] result = new FileSelector[selectorsList.size()]; + selectorsList.copyInto(result); + return result; } /** @@ -115,26 +111,6 @@ public abstract class BaseSelectorContainer extends BaseSelector } /** - * Performs the check for circular references and returns the - * referenced SelectorContainer. - */ - private SelectorContainer getRef(Project p) { - if (!checked) { - Stack stk = new Stack(); - stk.push(this); - dieOnCircularReference(stk, p); - } - - Object o = ref.getReferencedObject(p); - if (!(o instanceof SelectorContainer)) { - throw new BuildException(ref.getRefId() + - " doesn\'t denote a selector type"); - } else { - return (SelectorContainer) o; - } - } - - /** * Convert the Selectors within this container to a string. This will * just be a helper class for the subclasses that put their own name * around the contents listed here. @@ -163,9 +139,6 @@ public abstract class BaseSelectorContainer extends BaseSelector * @return the selector that was added */ public void appendSelector(FileSelector selector) { - if (isReference()) { - throw noChildrenAllowed(); - } selectorsList.addElement(selector); } @@ -215,7 +188,14 @@ public abstract class BaseSelectorContainer extends BaseSelector File file); - /* Methods below all implement the static selectors */ + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public void addSelector(SelectSelector selector) { + appendSelector(selector); + } /** * add an "And" selector entry on the selector list @@ -255,56 +235,56 @@ public abstract class BaseSelectorContainer extends BaseSelector /** * add a selector date entry on the selector list */ - public void addDateselect(DateSelector selector) { + public void addDate(DateSelector selector) { appendSelector(selector); } /** * add a selector size entry on the selector list */ - public void addSizeselect(SizeSelector selector) { + public void addSize(SizeSelector selector) { appendSelector(selector); } /** * add a selector filename entry on the selector list */ - public void addFilenameselect(FilenameSelector selector) { + public void addFilename(FilenameSelector selector) { appendSelector(selector); } /** * add an extended selector entry on the selector list */ - public void addExtendSelect(ExtendSelector selector) { + public void addCustom(ExtendSelector selector) { appendSelector(selector); } /** * add a contains selector entry on the selector list */ - public void addContainsSelect(ContainsSelector selector) { + public void addContains(ContainsSelector selector) { appendSelector(selector); } /** * add a present selector entry on the selector list */ - public void addPresentSelect(PresentSelector selector) { + public void addPresent(PresentSelector selector) { appendSelector(selector); } /** * add a depth selector entry on the selector list */ - public void addDepthSelect(DepthSelector selector) { + public void addDepth(DepthSelector selector) { appendSelector(selector); } /** * add a depends selector entry on the selector list */ - public void addDependSelect(DependSelector selector) { + public void addDepend(DependSelector selector) { appendSelector(selector); } diff --git a/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java b/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java index e7b505b44..dfe5b04b0 100644 --- a/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java @@ -75,7 +75,7 @@ public class ContainsSelector extends BaseExtendSelector { private String contains = null; private boolean casesensitive = true; - public final static String CONTAINS_KEY = "contains"; + public final static String CONTAINS_KEY = "text"; public final static String CASE_KEY = "casesensitive"; @@ -83,7 +83,7 @@ public class ContainsSelector extends BaseExtendSelector { } public String toString() { - StringBuffer buf = new StringBuffer("{containsselector contains: "); + StringBuffer buf = new StringBuffer("{containsselector text: "); buf.append(contains); buf.append(" casesensitive: "); if (casesensitive) { @@ -100,7 +100,7 @@ public class ContainsSelector extends BaseExtendSelector { * * @param contains the string that a file must contain to be selected. */ - public void setContains(String contains) { + public void setText(String contains) { this.contains = contains; } @@ -114,7 +114,7 @@ public class ContainsSelector extends BaseExtendSelector { } /** - * When using this as a dynamic selector, this method will be called. + * When using this as a custom selector, this method will be called. * It translates each parameter into the appropriate setXXX() call. * * @param parameters the complete set of parameters for this selector @@ -125,7 +125,7 @@ public class ContainsSelector extends BaseExtendSelector { for (int i = 0; i < parameters.length; i++) { String paramname = parameters[i].getName(); if (CONTAINS_KEY.equalsIgnoreCase(paramname)) { - setContains(parameters[i].getValue()); + setText(parameters[i].getValue()); } else if (CASE_KEY.equalsIgnoreCase(paramname)) { setCasesensitive(Project.toBoolean( @@ -145,7 +145,7 @@ public class ContainsSelector extends BaseExtendSelector { */ public void verifySettings() { if (contains == null) { - setError("The contains attribute is required"); + setError("The text attribute is required"); } } @@ -167,13 +167,20 @@ public class ContainsSelector extends BaseExtendSelector { return true; } + String userstr = contains; + if (!casesensitive) { + userstr = contains.toLowerCase(); + } BufferedReader in = null; try { in = new BufferedReader(new InputStreamReader( new FileInputStream(file))); String teststr = in.readLine(); while (teststr != null) { - if (teststr.indexOf(contains) > -1) { + if (!casesensitive) { + teststr = teststr.toLowerCase(); + } + if (teststr.indexOf(userstr) > -1) { return true; } teststr = in.readLine(); diff --git a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java index d72e45893..215253aa1 100644 --- a/src/main/org/apache/tools/ant/types/selectors/DateSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/DateSelector.java @@ -62,6 +62,7 @@ import java.util.Locale; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.taskdefs.condition.Os; /** * Selector that chooses files based on their last modified date. @@ -74,19 +75,24 @@ public class DateSelector extends BaseExtendSelector { private long millis = -1; private String dateTime = null; private boolean includeDirs = false; - private int cmp = 0; + private int granularity = 0; + private int cmp = 2; public final static String MILLIS_KEY = "millis"; public final static String DATETIME_KEY = "datetime"; public final static String CHECKDIRS_KEY = "checkdirs"; + public final static String GRANULARITY_KEY = "granularity"; public final static String WHEN_KEY = "when"; public DateSelector() { + if (Os.isFamily("dos")) { + granularity = 2000; + } } public String toString() { StringBuffer buf = new StringBuffer("{dateselector date: "); buf.append(dateTime); - buf.append("compare: "); + buf.append(" compare: "); if (cmp == 0) { buf.append("before"); } @@ -95,6 +101,8 @@ public class DateSelector extends BaseExtendSelector { } else { buf.append("equal"); } + buf.append(" granularity: "); + buf.append(granularity); buf.append("}"); return buf.toString(); } @@ -110,6 +118,13 @@ public class DateSelector extends BaseExtendSelector { } /** + * Returns the millisecond value the selector is set for. + */ + public long getMillis() { + return millis; + } + + /** * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM * format * @@ -147,6 +162,14 @@ public class DateSelector extends BaseExtendSelector { } /** + * Sets the number of milliseconds leeway we will give before we consider + * a file not to have matched a date. + */ + public void setGranularity(int granularity) { + this.granularity = granularity; + } + + /** * Sets the type of comparison to be done on the file's last modified * date. * @@ -157,7 +180,7 @@ public class DateSelector extends BaseExtendSelector { } /** - * When using this as a dynamic selector, this method will be called. + * When using this as a custom selector, this method will be called. * It translates each parameter into the appropriate setXXX() call. * * @param parameters the complete set of parameters for this selector @@ -182,6 +205,15 @@ public class DateSelector extends BaseExtendSelector { else if (CHECKDIRS_KEY.equalsIgnoreCase(paramname)) { setCheckdirs(Project.toBoolean(parameters[i].getValue())); } + else if (GRANULARITY_KEY.equalsIgnoreCase(paramname)) { + try { + setGranularity(new Integer(parameters[i].getValue() + ).intValue()); + } catch (NumberFormatException nfe) { + setError("Invalid granularity setting " + + parameters[i].getValue()); + } + } else if (WHEN_KEY.equalsIgnoreCase(paramname)) { TimeComparisons cmp = new TimeComparisons(); cmp.setValue(parameters[i].getValue()); @@ -225,13 +257,13 @@ public class DateSelector extends BaseExtendSelector { return true; } if (cmp == 0) { - return (file.lastModified() < millis); + return ((file.lastModified() - granularity) < millis); } else if (cmp == 1) { - return (file.lastModified() > millis); + return ((file.lastModified() + granularity) > millis); } else { - return (file.lastModified() == millis); + return (Math.abs(file.lastModified() - millis) <= granularity); } } diff --git a/src/main/org/apache/tools/ant/types/selectors/DependSelector.java b/src/main/org/apache/tools/ant/types/selectors/DependSelector.java index ceefdd7f9..f4d92a4a2 100644 --- a/src/main/org/apache/tools/ant/types/selectors/DependSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/DependSelector.java @@ -61,6 +61,7 @@ import org.apache.tools.ant.types.Mapper; import org.apache.tools.ant.util.IdentityMapper; import org.apache.tools.ant.util.FileNameMapper; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.condition.Os; /** * Selector that filters files based on whether they are newer than @@ -80,6 +81,9 @@ public class DependSelector extends BaseSelector { private int granularity = 0; public DependSelector() { + if (Os.isFamily("dos")) { + granularity = 2000; + } } public String toString() { @@ -171,6 +175,11 @@ public class DependSelector extends BaseSelector { // Determine file whose out-of-dateness is to be checked String[] destfiles = map.mapFileName(filename); + // If filename does not match the To attribute of the mapper + // then filter it out of the files we are considering + if (destfiles == null) { + return false; + } // Sanity check if (destfiles.length != 1 || destfiles[0] == null) { throw new BuildException("Invalid destination file results for " diff --git a/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java b/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java index 1b2002216..0742521cf 100644 --- a/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java @@ -106,7 +106,7 @@ public class DepthSelector extends BaseExtendSelector { } /** - * When using this as a dynamic selector, this method will be called. + * When using this as a custom selector, this method will be called. * It translates each parameter into the appropriate setXXX() call. * * @param parameters the complete set of parameters for this selector @@ -150,7 +150,7 @@ public class DepthSelector extends BaseExtendSelector { setError("You must set at least one of the min or the " + "max levels."); } - if (max < min) { + if (max < min && max > -1) { setError("The maximum depth is lower than the minimum."); } } diff --git a/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java b/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java index 25d968c9b..0d7fd10bc 100644 --- a/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java @@ -59,12 +59,12 @@ import java.io.File; import org.apache.tools.ant.types.Parameterizable; /** - * This is the interface to be used by all dynamic selectors, those that are - * called through the <extendselect> tag. It is the amalgamation of two + * This is the interface to be used by all custom selectors, those that are + * called through the <custom> tag. It is the amalgamation of two * interfaces, the FileSelector and the Paramterizable interface. Note that * you will almost certainly want the default behaviour for handling * Parameters, so you probably want to use the BaseExtendSelector class - * as the base class for your dynamic selector rather than implementing + * as the base class for your custom selector rather than implementing * this interface from scratch. * * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> diff --git a/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java b/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java index 9925fe971..46533c31f 100644 --- a/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java @@ -58,6 +58,7 @@ import java.io.File; import java.util.Vector; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.types.DataType; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Parameter; @@ -72,7 +73,7 @@ import org.apache.tools.ant.types.Reference; public class ExtendSelector extends BaseSelector { private String classname = null; - private ExtendFileSelector dynselector = null; + private FileSelector dynselector = null; private Vector paramVec = new Vector(); private Path classpath = null; @@ -83,7 +84,7 @@ public class ExtendSelector extends BaseSelector { } /** - * Sets the classname of the dynamic selector. + * Sets the classname of the custom selector. * * @param classname is the class which implements this selector */ @@ -92,13 +93,21 @@ public class ExtendSelector extends BaseSelector { } /** - * Instantiates the identified dynamic selector class. + * Instantiates the identified custom selector class. */ public void selectorCreate() { if (classname != null && classname.length() > 0) { try { - dynselector = (ExtendFileSelector) - Class.forName(classname).newInstance(); + Class c = null; + if (classpath == null) { + c = Class.forName(classname); + } else { + AntClassLoader al = new AntClassLoader(getProject(), + classpath); + c = al.loadClass(classname); + AntClassLoader.initializeClass(c); + } + dynselector = (FileSelector) c.newInstance(); } catch (ClassNotFoundException cnfexcept) { setError("Selector " + classname + @@ -118,7 +127,7 @@ public class ExtendSelector extends BaseSelector { } /** - * Create new parameters to pass to dynamic selector. + * Create new parameters to pass to custom selector. * * @param p The new Parameter object */ @@ -162,7 +171,7 @@ public class ExtendSelector extends BaseSelector { } /** - * Set the classpath to use for loading a dynamic selector by using + * Set the classpath to use for loading a custom selector by using * a reference. */ public void setClasspathref(Reference r) { @@ -174,37 +183,45 @@ public class ExtendSelector extends BaseSelector { /** * These are errors specific to ExtendSelector only. If there are - * errors in the dynamic selector, it should throw a BuildException + * errors in the custom selector, it should throw a BuildException * when isSelected() is called. */ public void verifySettings() { + // Creation is done here rather than in isSelected() because some + // containers may do a validation pass before running isSelected(), + // but we need to check for the existence of the created class. + if (dynselector == null) { + selectorCreate(); + } if (classname == null || classname.length() < 1) { setError("The classname attribute is required"); } else if (dynselector == null) { - setError("Internal Error: The dynamic selector is not set"); + setError("Internal Error: The custom selector was not created"); + } + else if (!(dynselector instanceof ExtendFileSelector) && + (paramVec.size() > 0)) { + setError("Cannot set parameters on custom selector that does not " + + "implement ExtendFileSelector"); } } /** - * Allows the dynamic selector to choose whether to select a file. This - * is also where the Parameters are passed to the dynamic selector, + * Allows the custom selector to choose whether to select a file. This + * is also where the Parameters are passed to the custom selector, * since we know we must have them all by now. And since we must know * both classpath and classname, creating the class is deferred to here * as well. */ public boolean isSelected(File basedir, String filename, File file) throws BuildException { - if (dynselector == null) { - selectorCreate(); - } validate(); - if (paramVec.size() > 0) { + if (paramVec.size() > 0 && dynselector instanceof ExtendFileSelector) { Parameter[] paramArray = new Parameter[paramVec.size()]; paramVec.copyInto(paramArray); // We know that dynselector must be non-null if no error message - dynselector.setParameters(paramArray); + ((ExtendFileSelector)dynselector).setParameters(paramArray); } return dynselector.isSelected(basedir,filename,file); } diff --git a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java index 1706790bb..3c8b2b4f5 100644 --- a/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java @@ -123,9 +123,9 @@ public class FilenameSelector extends BaseExtendSelector { /** * You can optionally reverse the selection of this selector, - * thereby emulating an <exclude> tag, by setting the attribute + * thereby emulating an <exclude> tag, by setting the attribute * negate to true. This is identical to surrounding the selector - * with <not></not>. + * with <not></not>. * * @param negated whether to negate this selection */ @@ -134,7 +134,7 @@ public class FilenameSelector extends BaseExtendSelector { } /** - * When using this as a dynamic selector, this method will be called. + * When using this as a custom selector, this method will be called. * It translates each parameter into the appropriate setXXX() call. * * @param parameters the complete set of parameters for this selector @@ -187,8 +187,8 @@ public class FilenameSelector extends BaseExtendSelector { public boolean isSelected(File basedir, String filename, File file) { validate(); - return SelectorUtils.matchPath(pattern,filename, - casesensitive); + return (SelectorUtils.matchPath(pattern,filename, + casesensitive) == !(negated)); } } diff --git a/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java b/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java index 9efab0f0a..eba5848ed 100644 --- a/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java @@ -184,6 +184,11 @@ public class PresentSelector extends BaseSelector { // Determine file whose existence is to be checked String[] destfiles = map.mapFileName(filename); + // If filename does not match the To attribute of the mapper + // then filter it out of the files we are considering + if (destfiles == null) { + return false; + } // Sanity check if (destfiles.length != 1 || destfiles[0] == null) { throw new BuildException("Invalid destination file results for " diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java b/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java new file mode 100644 index 000000000..535b537e0 --- /dev/null +++ b/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java @@ -0,0 +1,169 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 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.selectors; + +import java.io.File; +import java.util.Enumeration; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Reference; + +/** + * This selector just holds one other selector and forwards all + * requests to it. It exists so that there is a single selector + * type that can exist outside of any targets, as an element of + * project. It overrides all of the reference stuff so that it + * works as expected. Note that this is the only selector you + * can reference. + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + * @since 1.5 + */ +public class SelectSelector extends AndSelector { + + /** + * Default constructor. + */ + public SelectSelector() { + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + if (hasSelectors()) { + buf.append("{select: "); + buf.append(super.toString()); + buf.append("}"); + } + return buf.toString(); + } + + /** + * Performs the check for circular references and returns the + * referenced Selector. + */ + private SelectSelector getRef() { + Object o = getCheckedRef(this.getClass(), "SelectSelector"); + return (SelectSelector) o; + } + + /** + * Indicates whether there are any selectors here. + */ + public boolean hasSelectors() { + if (isReference()) { + return getRef().hasSelectors(); + } + return super.hasSelectors(); + } + + /** + * Gives the count of the number of selectors in this container + */ + public int selectorCount() { + if (isReference()) { + return getRef().selectorCount(); + } + return super.selectorCount(); + } + + /** + * Returns the set of selectors as an array. + */ + public FileSelector[] getSelectors(Project p) { + if (isReference()) { + return getRef().getSelectors(p); + } + return super.getSelectors(p); + } + + /** + * Returns an enumerator for accessing the set of selectors. + */ + public Enumeration selectorElements() { + if (isReference()) { + return getRef().selectorElements(); + } + return super.selectorElements(); + } + + /** + * Add a new selector into this container. + * + * @param selector the new selector to add + * @return the selector that was added + */ + public void appendSelector(FileSelector selector) { + if (isReference()) { + throw noChildrenAllowed(); + } + super.appendSelector(selector); + } + + + + /** + * Makes sure that there is only one entry, sets an error message if + * not. + */ + public void verifySettings() { + if (selectorCount() != 1) { + setError("One and only one selector is allowed within the " + + "<select> tag"); + } + } + +} + diff --git a/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java b/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java index 819e88fa9..66382d811 100644 --- a/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java +++ b/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java @@ -64,7 +64,7 @@ import java.util.Stack; import java.util.Vector; /** - * This is the base class for selectors that can contain other selectors. + * This is the interface for selectors that can contain other selectors. * * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> * @since 1.5 @@ -107,7 +107,12 @@ public interface SelectorContainer { */ public void appendSelector(FileSelector selector); - /* Methods below all implement the static selectors */ + /* Methods below all add specific selectors */ + + /** + * add a "Select" selector entry on the selector list + */ + public void addSelector(SelectSelector selector); /** * add an "And" selector entry on the selector list @@ -137,42 +142,42 @@ public interface SelectorContainer { /** * add a selector date entry on the selector list */ - public void addDateselect(DateSelector selector); + public void addDate(DateSelector selector); /** * add a selector size entry on the selector list */ - public void addSizeselect(SizeSelector selector); + public void addSize(SizeSelector selector); /** * add a selector filename entry on the selector list */ - public void addFilenameselect(FilenameSelector selector); + public void addFilename(FilenameSelector selector); /** * add an extended selector entry on the selector list */ - public void addExtendSelect(ExtendSelector selector); + public void addCustom(ExtendSelector selector); /** * add a contains selector entry on the selector list */ - public void addContainsSelect(ContainsSelector selector); + public void addContains(ContainsSelector selector); /** * add a present selector entry on the selector list */ - public void addPresentSelect(PresentSelector selector); + public void addPresent(PresentSelector selector); /** * add a depth selector entry on the selector list */ - public void addDepthSelect(DepthSelector selector); + public void addDepth(DepthSelector selector); /** * add a depends selector entry on the selector list */ - public void addDependSelect(DependSelector selector); + public void addDepend(DependSelector selector); } diff --git a/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java b/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java index 3ed87a44b..52e883da3 100644 --- a/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java +++ b/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java @@ -71,16 +71,16 @@ public class SizeSelector extends BaseExtendSelector { private long size = -1; private long multiplier = 1; private long sizelimit = -1; - private int cmp = 0; - public final static String SIZE_KEY = "millis"; - public final static String UNITS_KEY = "datetime"; + private int cmp = 2; + public final static String SIZE_KEY = "value"; + public final static String UNITS_KEY = "units"; public final static String WHEN_KEY = "when"; public SizeSelector() { } public String toString() { - StringBuffer buf = new StringBuffer("{sizeselector size: "); + StringBuffer buf = new StringBuffer("{sizeselector value: "); buf.append(sizelimit); buf.append("compare: "); if (cmp == 0) { @@ -102,7 +102,7 @@ public class SizeSelector extends BaseExtendSelector { * * @param size the size to select against expressed in units */ - public void setSize(long size) { + public void setValue(long size) { this.size = size; if ((multiplier != 0) && (size > -1)) { sizelimit = size * multiplier; @@ -179,7 +179,7 @@ public class SizeSelector extends BaseExtendSelector { } /** - * When using this as a dynamic selector, this method will be called. + * When using this as a custom selector, this method will be called. * It translates each parameter into the appropriate setXXX() call. * * @param parameters the complete set of parameters for this selector @@ -191,7 +191,7 @@ public class SizeSelector extends BaseExtendSelector { String paramname = parameters[i].getName(); if (SIZE_KEY.equalsIgnoreCase(paramname)) { try { - setSize(new Long(parameters[i].getValue() + setValue(new Long(parameters[i].getValue() ).longValue()); } catch (NumberFormatException nfe) { setError("Invalid size setting " @@ -227,7 +227,7 @@ public class SizeSelector extends BaseExtendSelector { */ public void verifySettings() { if (size < 0) { - setError("The size attribute is required, and must be positive"); + setError("The value attribute is required, and must be positive"); } else if (multiplier < 1) { setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti"); diff --git a/src/main/org/apache/tools/ant/util/FileUtils.java b/src/main/org/apache/tools/ant/util/FileUtils.java index cb8acbbab..b6a5dc8ae 100644 --- a/src/main/org/apache/tools/ant/util/FileUtils.java +++ b/src/main/org/apache/tools/ant/util/FileUtils.java @@ -781,6 +781,10 @@ public class FileUtils { * Read from reader till EOF */ public static final String readFully(Reader rdr, int bufferSize) throws IOException { + if (bufferSize <= 0) { + throw new IllegalArgumentException("Buffer size must be greater " + + "than 0"); + } final char[] buffer = new char[bufferSize]; int bufferLength = 0; String text = null; @@ -831,5 +835,48 @@ public class FileUtils { return false; } + /** + * Checks whether a given file is a symbolic link. + * + * <p>It doesn't really test for symbolic links but whether the + * canonical and absolute paths of the file are identical - this + * may lead to false positives on some platforms.</p> + * + * @param parent the parent directory of the file to test + * @param name the name of the file to test. + * + * @since Ant 1.5 + */ + public boolean isSymbolicLink(File parent, String name) + throws IOException { + File resolvedParent = new File(parent.getCanonicalPath()); + File toTest = new File(resolvedParent, name); + return !toTest.getAbsolutePath().equals(toTest.getCanonicalPath()); + } + + /** + * Removes a leading path from a second path. + * + * @param leading The leading path, must not be null, must be absolute. + * @param path The path to remove from, must not be null, must be absolute. + * + * @return path's normalized absolute if it doesn't start with + * leading, path's path with leading's path removed otherwise. + * + * @since Ant 1.5 + */ + public String removeLeadingPath(File leading, File path) { + String l = normalize(leading.getAbsolutePath()).getAbsolutePath(); + String p = normalize(path.getAbsolutePath()).getAbsolutePath(); + if (p.startsWith(l)) { + String result = p.substring(l.length()); + if (result.startsWith(File.separator)) { + result = result.substring(File.separator.length()); + } + return result; + } else { + return p; + } + } } diff --git a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java index 549212fd9..2db98cb16 100644 --- a/src/main/org/apache/tools/ant/util/JavaEnvUtils.java +++ b/src/main/org/apache/tools/ant/util/JavaEnvUtils.java @@ -164,14 +164,18 @@ public class JavaEnvUtils { return command; } - File jExecutable = findInDir(javaHome + "/bin", command); + File jExecutable = null; - if (jExecutable == null && isAix) { + if (isAix) { // On IBM's JDK 1.2 the directory layout is different, 1.3 follows // Sun's layout. jExecutable = findInDir(javaHome + "/sh", command); } + if (jExecutable == null) { + jExecutable = findInDir(javaHome + "/bin", command); + } + if (jExecutable != null) { return jExecutable.getAbsolutePath(); } else { @@ -200,19 +204,24 @@ public class JavaEnvUtils { return command; } - File jExecutable = findInDir(javaHome + "/../bin", command); + File jExecutable = null; - if (jExecutable == null && isAix) { + if (isAix) { // On IBM's JDK 1.2 the directory layout is different, 1.3 follows // Sun's layout. jExecutable = findInDir(javaHome + "/../sh", command); } + if (jExecutable == null) { + jExecutable = findInDir(javaHome + "/../bin", command); + } + if (jExecutable != null) { return jExecutable.getAbsolutePath(); } else { // fall back to JRE bin directory, also catches JDK 1.0 and 1.1 - // where java.home points to the root of the JDK + // where java.home points to the root of the JDK and Mac OS X where + // the whole directory layout is different from Sun's return getJreExecutable(command); } } diff --git a/src/script/ant b/src/script/ant index 3609e8196..3d00feb69 100644 --- a/src/script/ant +++ b/src/script/ant @@ -110,7 +110,7 @@ if $rpm_mode; then if [ -z "$LOCALCLASSPATH" ] ; then LOCALCLASSPATH=$JAVALIBDIR/$i.jar else - LOCALCLASSPATH="$i.jar":"$LOCALCLASSPATH" + LOCALCLASSPATH="$JAVALIBDIR/$i.jar":"$LOCALCLASSPATH" fi done else @@ -175,6 +175,7 @@ if $cygwin; then JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` CLASSPATH=`cygpath --path --windows "$CLASSPATH"` LOCALCLASSPATH=`cygpath --path --windows "$LOCALCLASSPATH"` + ANT_OPTS="$ANT_OPTS -Dcygwin.user.home="`cygpath --path --windows "$HOME"` fi "$JAVACMD" -classpath "$LOCALCLASSPATH" -Dant.home="${ANT_HOME}" $ANT_OPTS org.apache.tools.ant.Main $ANT_ARGS "$@" diff --git a/src/script/runant.pl b/src/script/runant.pl index f4e506786..9b7257ed3 100644 --- a/src/script/runant.pl +++ b/src/script/runant.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl # -# Copyright (c) 2001 The Apache Software Foundation. All rights +# Copyright (c) 2001-2002 The Apache Software Foundation. All rights # reserved. # ####################################################################### @@ -55,11 +55,18 @@ if ($HOME eq "") my $JAVACMD = $ENV{JAVACMD}; $JAVACMD = "java" if $JAVACMD eq ""; +my $onnetware = 0; +if ($^O eq "NetWare") +{ + $onnetware = 1; +} + #ISSUE: what java wants to split up classpath varies from platform to platform #and perl is not too hot at hinting which box it is on. -#here I assume ":" 'cept on win32 and dos. Add extra tests here as needed. +#here I assume ":" 'cept on win32, dos, and netware. Add extra tests here as needed. my $s=":"; -if(($^O eq "MSWin32") || ($^O eq "dos") || ($^O eq "cygwin")) +if(($^O eq "MSWin32") || ($^O eq "dos") || ($^O eq "cygwin") || + ($onnetware == 1)) { $s=";"; } @@ -71,6 +78,13 @@ if ($localpath eq "") print "warning: no initial classpath\n" if ($debug); $localpath=""; } +if ($onnetware == 1) +{ +# avoid building a command line bigger than 512 characters - make localpath +# only include the "extra" stuff, and add in the system classpath as an expanded +# variable. + $localpath=""; +} #add jar files. I am sure there is a perl one liner to do this. my $jarpattern="$HOME/lib/*.jar"; @@ -117,7 +131,18 @@ if($ENV{JIKESPATH} ne "") #construct arguments to java my @ARGS; -push @ARGS, "-classpath", "$localpath", "-Dant.home=$HOME"; +if ($onnetware == 1) +{ +# make classpath literally $CLASSPATH; and then the contents of $localpath +# this is to avoid pushing us over the 512 character limit +# even skip the ; - that is already in $localpath + push @ARGS, "-classpath", "\$CLASSPATH$localpath"; +} +else +{ + push @ARGS, "-classpath", "$localpath"; +} +push @ARGS, "-Dant.home=$HOME"; push @ARGS, @ANT_OPTS; push @ARGS, "org.apache.tools.ant.Main", @ANT_ARGS; push @ARGS, @ARGV; diff --git a/src/testcases/org/apache/tools/ant/AntClassLoaderTest.java b/src/testcases/org/apache/tools/ant/AntClassLoaderTest.java new file mode 100644 index 000000000..8fddd349a --- /dev/null +++ b/src/testcases/org/apache/tools/ant/AntClassLoaderTest.java @@ -0,0 +1,112 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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; +import org.apache.tools.ant.types.Path; +import junit.framework.TestCase; + +/** + * Test case for ant class loader + * + * @author Conor MacNeill</a> + */ +public class AntClassLoaderTest extends TestCase { + + private Project p; + + public AntClassLoaderTest(String name) { + super(name); + } + + public void setUp() { + p = new Project(); + p.init(); + } + + public void testCleanup() throws BuildException { + Path path = new Path(p, "."); + AntClassLoader loader = new AntClassLoader(p, path); + try { + // we don't expect to find this + loader.findClass("fubar"); + fail("Did not expect to find fubar class"); + } catch (ClassNotFoundException e) { + // ignore expected + } + + loader.cleanup(); + try { + // we don't expect to find this + loader.findClass("fubar"); + fail("Did not expect to find fubar class"); + } catch (ClassNotFoundException e) { + // ignore expected + } catch (NullPointerException e) { + fail("loader should not fail even if cleaned up"); + } + + // tell the build it is finished + p.fireBuildFinished(null); + try { + // we don't expect to find this + loader.findClass("fubar"); + fail("Did not expect to find fubar class"); + } catch (ClassNotFoundException e) { + // ignore expected + } catch (NullPointerException e) { + fail("loader should not fail even if project finished"); + } + } +} + diff --git a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java index 024e9a0d2..d31b6a7f3 100644 --- a/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java +++ b/src/testcases/org/apache/tools/ant/DirectoryScannerTest.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2001 The Apache Software Foundation. All rights + * Copyright (c) 2001-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,9 +54,12 @@ package org.apache.tools.ant; +import org.apache.tools.ant.taskdefs.condition.Os; + import junit.framework.TestCase; import junit.framework.AssertionFailedError; import java.io.File; +import java.io.IOException; /** * JUnit 3 testcases for org.apache.tools.ant.DirectoryScanner @@ -67,6 +70,95 @@ public class DirectoryScannerTest extends TestCase { public DirectoryScannerTest(String name) {super(name);} + + // keep track of what operating systems are supported here. + private boolean supportsSymlinks = Os.isFamily("unix"); + + /** + * Test case for setFollowLinks() and associated funtionality. + * Only supports test on linux, at the moment because Java has + * no real notion of symlinks built in, so an os-specfic call + * to Runtime.exec() must be made to create a link to test against. + */ + + public void testSetFollowLinks() { + if (supportsSymlinks) { + try { + // add conditions and more commands as soon as the need arises + String[] command = new String[] { + "ln", "-s", "ant", "src/main/org/apache/tools/ThisIsALink" + }; + try { + Runtime.getRuntime().exec(command); + // give ourselves some time for the system call + // to execute... tweak if you have a really over + // loaded system. + Thread.sleep(1000); + } catch (IOException ioe) { + fail("IOException making link "+ioe); + } catch (InterruptedException ie) { + } + + File dir = new File("src/main/org/apache/tools"); + DirectoryScanner ds = new DirectoryScanner(); + + // followLinks should be true by default, but if this ever + // changes we will need this line. + ds.setFollowSymlinks(true); + + ds.setBasedir(dir); + ds.setExcludes(new String[] {"ant/**"}); + ds.scan(); + + boolean haveZipPackage = false; + boolean haveTaskdefsPackage = false; + + String[] included = ds.getIncludedDirectories(); + for (int i=0; i<included.length; i++) { + if (included[i].equals("zip")) { + haveZipPackage = true; + } else if (included[i].equals("ThisIsALink"+File.separator+ + "taskdefs")) { + haveTaskdefsPackage = true; + } + } + + // if we followed the symlink we just made we should + // bypass the excludes. + + assertTrue("(1) zip package included", haveZipPackage); + assertTrue("(1) taskdefs package included", + haveTaskdefsPackage); + + + ds = new DirectoryScanner(); + ds.setFollowSymlinks(false); + + ds.setBasedir(dir); + ds.setExcludes(new String[] {"ant/**"}); + ds.scan(); + + haveZipPackage = false; + haveTaskdefsPackage = false; + included = ds.getIncludedDirectories(); + for (int i=0; i<included.length; i++) { + if (included[i].equals("zip")) { + haveZipPackage = true; + } else if (included[i].equals("ThisIsALink"+File.separator+ + "taskdefs")) { + haveTaskdefsPackage = true; + } + } + assertTrue("(2) zip package included", haveZipPackage); + assertTrue("(2) taskdefs package not included", + !haveTaskdefsPackage); + + } finally { + (new File("src/main/org/apache/tools/ThisIsALink")).delete(); + } + } + } + /** * Test inspired by Bug#1415. */ diff --git a/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java b/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java index d41970806..08775a5ad 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/AntTest.java @@ -161,6 +161,7 @@ public class AntTest extends BuildFileTest { if (ae != null) { throw ae; } + project.removeBuildListener(bc); } public void testReferenceInheritance() { @@ -252,6 +253,22 @@ public class AntTest extends BuildFileTest { getProject().removeBuildListener(ic); } + public void testRefId() { + Path testPath = new Path(project); + testPath.createPath().setPath(System.getProperty("java.class.path")); + PropertyChecker pc = + new PropertyChecker("testprop", + new String[] {null, + testPath.toString()}); + project.addBuildListener(pc); + executeTarget("testRefid"); + AssertionFailedError ae = pc.getError(); + if (ae != null) { + throw ae; + } + project.removeBuildListener(pc); + } + private class BasedirChecker implements BuildListener { private String[] expectedBasedirs; private int calls = 0; @@ -271,13 +288,8 @@ public class AntTest extends BuildFileTest { public void targetStarted(BuildEvent event) { if (error == null) { try { - if (calls == expectedBasedirs.length) { - assertEquals("cleanup", - event.getTarget().getName()); - } else { - assertEquals(expectedBasedirs[calls++], - event.getProject().getBaseDir().getAbsolutePath()); - } + assertEquals(expectedBasedirs[calls++], + event.getProject().getBaseDir().getAbsolutePath()); } catch (AssertionFailedError e) { error = e; } @@ -404,4 +416,40 @@ public class AntTest extends BuildFileTest { } + private class PropertyChecker implements BuildListener { + private String[] expectedValues; + private String key; + private int calls = 0; + private AssertionFailedError error; + + PropertyChecker(String key, String[] values) { + this.key = key; + this.expectedValues = values; + } + + public void buildStarted(BuildEvent event) {} + public void buildFinished(BuildEvent event) {} + public void targetFinished(BuildEvent event){} + public void taskStarted(BuildEvent event) {} + public void taskFinished(BuildEvent event) {} + public void messageLogged(BuildEvent event) {} + + public void targetStarted(BuildEvent event) { + if (error == null) { + try { + assertEquals(expectedValues[calls++], + event.getProject().getProperty(key)); + } catch (AssertionFailedError e) { + error = e; + } + } + } + + AssertionFailedError getError() { + return error; + } + + } + + } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/AvailableTest.java b/src/testcases/org/apache/tools/ant/taskdefs/AvailableTest.java index 2006590c1..737193ba4 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/AvailableTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/AvailableTest.java @@ -201,10 +201,6 @@ public class AvailableTest extends BuildFileTest { // Core class that exists in system classpath is ignored, but found in specified classpath public void test21() { - if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) { - // java.* classes are not found in JDK 1.1 even if specified in classpath attribute; test24 shows correct operation - return; - } executeTarget("test21"); assertEquals("true",project.getProperty("test")); } @@ -226,4 +222,16 @@ public class AvailableTest extends BuildFileTest { executeTarget("test24"); assertEquals("true",project.getProperty("test")); } + + // File is not found in specified filepath + public void testSearchInPathNotThere() { + executeTarget("searchInPathNotThere"); + assertNull(project.getProperty("test")); + } + + // File is not found in specified filepath + public void testSearchInPathIsThere() { + executeTarget("searchInPathIsThere"); + assertEquals("true",project.getProperty("test")); + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/ConditionTest.java b/src/testcases/org/apache/tools/ant/taskdefs/ConditionTest.java index 92a5c59c0..cecac4985 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/ConditionTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/ConditionTest.java @@ -190,6 +190,15 @@ public class ConditionTest extends BuildFileTest { expectPropertySet("filesmatch-match","filesmatch-match"); } + public void testFilesmatchDifferentSizes() { + expectPropertyUnset("filesmatch-different-sizes", + "filesmatch-different-sizes"); + } + + public void testFilesmatchDifferentOnemissing() { + expectPropertyUnset("filesmatch-different-onemissing", + "filesmatch-different-onemissing"); + } public void testContains() { expectPropertySet("contains","contains"); diff --git a/src/testcases/org/apache/tools/ant/taskdefs/FilterTest.java b/src/testcases/org/apache/tools/ant/taskdefs/FilterTest.java index a8ce9870c..dd3bff63b 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/FilterTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/FilterTest.java @@ -119,6 +119,12 @@ public class FilterTest extends BuildFileTest { getFilteredFile("8", "taskdefs.tmp/filter2.txt")); } + public void test9() { + executeTarget("test9"); + assertEquals("included", + getFilteredFile("9", "taskdefs.tmp/filter3.txt")); + } + private String getFilteredFile(String testNumber, String filteredFile) { String line = null; diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java index 8b31f1999..e30d64c36 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java @@ -80,6 +80,7 @@ public class EchoPropertiesTest extends BuildFileTest { private static final String GOOD_OUTFILE_XML = "test.xml"; private static final String PREFIX_OUTFILE = "test-prefix.properties"; private static final String TEST_VALUE = "isSet"; + private static final String BAD_OUTFILE = "."; public EchoPropertiesTest(String name) { super(name); @@ -230,6 +231,25 @@ public class EchoPropertiesTest extends BuildFileTest { props.list(System.out); assertEquals("test property not found ", TEST_VALUE, props.getProperty("test.property")); +/* + // read in the file + FileReader fr = new FileReader( f ); + try { + BufferedReader br = new BufferedReader( fr ); + String read = null; + while ( (read = br.readLine()) != null) + { + if (read.indexOf("test.property" + TEST_VALUE) >= 0) + { + // found the property we set - it's good. + return; + } + } + fail( "did not encounter set property in generated file." ); + } finally { + try { fr.close(); } catch(IOException e) {} + } +*/ } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java index 95b2e179b..71b76cc80 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java @@ -131,6 +131,7 @@ public class PropertyFileTest extends BuildFileTest { assertEquals("2003/01/21", project.getProperty("first.birthday")); assertEquals("0124", project.getProperty("olderThanAWeek")); assertEquals("37", project.getProperty("existing.prop")); + assertEquals("6",project.getProperty("int.without.value")); } /* diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java index ecb12a950..c532227e7 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java @@ -118,5 +118,11 @@ public class XmlValidateTest extends BuildFileTest { public void testXmlCatalog() { executeTarget("xmlcatalog"); } -} + /** + * Test nested xmlcatalog definitions + */ + public void testXmlCatalogNested() { + executeTarget("xmlcatalognested"); + } +} diff --git a/src/testcases/org/apache/tools/ant/types/PathTest.java b/src/testcases/org/apache/tools/ant/types/PathTest.java index ea661bc5a..b18eaded0 100644 --- a/src/testcases/org/apache/tools/ant/types/PathTest.java +++ b/src/testcases/org/apache/tools/ant/types/PathTest.java @@ -282,6 +282,32 @@ public class PathTest extends TestCase { assertTrue("temp resolved relative to project\'s basedir", l[3].endsWith("\\temp")); } + + // try a multi-part netware-volume length path with UNIX + // separator (this testcase if from an actual bug that was + // found, in AvailableTest, which uses PathTokenizer) + p = new Path(project, + "SYS:\\JAVA/lib/rt.jar:SYS:\\JAVA/lib/classes.zip"); + l = p.list(); + if (isUnixStyle) { + assertEquals("no drives on Unix", 3, l.length); + assertTrue("sys resolved relative to project\'s basedir", + l[0].endsWith("/SYS")); + assertEquals("/JAVA/lib/rt.jar", l[1]); + assertEquals("/JAVA/lib/classes.zip", l[2]); + } else if (isNetWare) { + assertEquals("volumes on NetWare", 2, l.length); + assertEquals("sys:\\java\\lib\\rt.jar", l[0].toLowerCase(Locale.US)); + assertEquals("sys:\\java\\lib\\classes.zip", l[1].toLowerCase(Locale.US)); + } else { + assertEquals("no multiple character-length volumes on Windows", 3, l.length); + assertTrue("sys resolved relative to project\'s basedir", + l[0].endsWith("\\SYS")); + assertTrue("java/lib/rt.jar resolved relative to project\'s basedir", + l[1].endsWith("\\JAVA\\lib\\rt.jar")); + assertTrue("java/lib/classes.zip resolved relative to project\'s basedir", + l[2].endsWith("\\JAVA\\lib\\classes.zip")); + } } public void testConstructorMixedStyle() { diff --git a/src/testcases/org/apache/tools/ant/types/XMLCatalogTest.java b/src/testcases/org/apache/tools/ant/types/XMLCatalogTest.java new file mode 100644 index 000000000..d0eb16e66 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/XMLCatalogTest.java @@ -0,0 +1,425 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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 org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.FileUtils; + +import junit.framework.TestCase; + +import java.io.File; + +import java.net.MalformedURLException; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; + +/** + * JUnit testcases for org.apache.tools.ant.types.XMLCatalog + * + * @author <a href="mailto:cstrong@arielpartners.com">Craeg Strong</a> + * @version $Id$ + */ +public class XMLCatalogTest extends TestCase { + + private Project project; + private XMLCatalog catalog; + private FileUtils fileUtils = FileUtils.newFileUtils(); + + private XMLCatalog newCatalog() { + XMLCatalog cat = new XMLCatalog(); + cat.setProject(project); + return cat; + } + + private String toURLString(File file) throws MalformedURLException { + return fileUtils.getFileURL(file).toString(); + } + + public XMLCatalogTest(String name) { + super(name); + } + + public void setUp() { + project = new Project(); + project.setBasedir("."); + + // This causes XMLCatalog to print out detailed logging + // messages for debugging + // + // DefaultLogger logger = new DefaultLogger(); + // logger.setMessageOutputLevel(Project.MSG_DEBUG); + // logger.setOutputPrintStream(System.out); + // logger.setErrorPrintStream(System.err); + // project.addBuildListener(logger); + + catalog = newCatalog(); + } + + public void tearDown() { + project = null; + catalog = null; + } + + public void testEmptyCatalog() { + try { + InputSource result = catalog.resolveEntity("PUBLIC ID ONE", + "i/dont/exist.dtd"); + assertNull("Empty catalog should return null", result); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + try { + Source result = catalog.resolve("i/dont/exist.dtd", null); + assertNull("Empty catalog should return null", result); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + } + + public void testNonExistentEntry() { + + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId("PUBLIC ID ONE"); + dtd.setLocation("i/dont/exist.dtd"); + + try { + InputSource result = catalog.resolveEntity("PUBLIC ID ONE", + "i/dont/exist.dtd"); + assertNull("Nonexistent Catalog entry should not be returned", result); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + try { + Source result = catalog.resolve("i/dont/exist.dtd", null); + assertNull("Nonexistent Catalog entry should not be returned", result); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + } + + public void testEmptyElementIfIsReference() { + try { + catalog.setRefid(new Reference("dummyref")); + fail("Can add reference to nonexistent XMLCatalog"); + } catch (BuildException be) { + assertEquals("Reference dummyref not found.", + be.getMessage()); + } + + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId("PUBLIC ID ONE"); + dtd.setLocation("i/dont/exist.dtd"); + catalog.addDTD(dtd); + project.addReference("catalog", catalog); + + try { + catalog.setRefid(new Reference("dummyref")); + fail("Can add reference to nonexistent XMLCatalog"); + } catch (BuildException be) { + assertEquals("You must not specify more than one " + + "attribute when using refid", be.getMessage()); + } + + XMLCatalog catalog2 = newCatalog(); + catalog2.setRefid(new Reference("catalog")); + + try { + catalog2.addConfiguredXMLCatalog(catalog); + fail("Can add nested XMLCatalog to XMLCatalog that is a reference"); + } catch (BuildException be) { + assertEquals("You must not specify nested elements when using refid", + be.getMessage()); + } + } + + public void testCircularReferenceCheck() { + + // catalog <--> catalog + project.addReference("catalog", catalog); + catalog.setRefid(new Reference("catalog")); + + try { + InputSource result = catalog.resolveEntity("PUBLIC ID ONE", + "i/dont/exist.dtd"); + fail("Can make XMLCatalog a Reference to itself."); + } catch (BuildException be) { + assertEquals("This data type contains a circular reference.", + be.getMessage()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + // catalog1 --> catalog2 --> catalog3 --> catalog1 + XMLCatalog catalog1 = newCatalog(); + project.addReference("catalog1", catalog1); + XMLCatalog catalog2 = newCatalog(); + project.addReference("catalog2", catalog2); + XMLCatalog catalog3 = newCatalog(); + project.addReference("catalog3", catalog3); + + catalog3.setRefid(new Reference("catalog1")); + catalog2.setRefid(new Reference("catalog3")); + catalog1.setRefid(new Reference("catalog2")); + + try { + InputSource result = catalog1.resolveEntity("PUBLIC ID ONE", + "i/dont/exist.dtd"); + fail("Can make circular reference"); + } catch (BuildException be) { + assertEquals("This data type contains a circular reference.", + be.getMessage()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + } + + public void testSimpleEntry() { + + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId("-//stevo//DTD doc 1.0//EN"); + String sysid = "src/etc/testcases/taskdefs/optional/xml/doc.dtd"; + dtd.setLocation(sysid); + catalog.addDTD(dtd); + File dtdFile = project.resolveFile(sysid); + + try { + InputSource result = catalog.resolveEntity("-//stevo//DTD doc 1.0//EN", + "nap:chemical+brothers"); + assertNotNull(result); + assertEquals(toURLString(dtdFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + } + + public void testEntryReference() { + + String publicId = "-//stevo//DTD doc 1.0//EN"; + String sysid = "src/etc/testcases/taskdefs/optional/xml/doc.dtd"; + + // catalog2 --> catalog1 --> catalog + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId(publicId); + dtd.setLocation(sysid); + catalog.addDTD(dtd); + File dtdFile = project.resolveFile(sysid); + + String uri = "http://foo.com/bar/blah.xml"; + String uriLoc = "src/etc/testcases/taskdefs/optional/xml/about.xml"; + + DTDLocation entity = new DTDLocation(); + entity.setPublicId(uri); + entity.setLocation(uriLoc); + catalog.addEntity(entity); + File xmlFile = project.resolveFile(uriLoc); + + project.addReference("catalog", catalog); + + XMLCatalog catalog1 = newCatalog(); + project.addReference("catalog1", catalog1); + XMLCatalog catalog2 = newCatalog(); + project.addReference("catalog2", catalog1); + + catalog1.setRefid(new Reference("catalog")); + catalog2.setRefid(new Reference("catalog1")); + + try { + InputSource result = catalog2.resolveEntity(publicId, + "nap:chemical+brothers"); + + assertNotNull(result); + assertEquals(toURLString(dtdFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + try { + Source result = catalog.resolve(uri, null); + assertNotNull(result); + assertEquals(toURLString(xmlFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + } + + public void testNestedCatalog() { + + String publicId = "-//stevo//DTD doc 1.0//EN"; + String dtdLoc = "src/etc/testcases/taskdefs/optional/xml/doc.dtd"; + + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId(publicId); + dtd.setLocation(dtdLoc); + catalog.addDTD(dtd); + File dtdFile = project.resolveFile(dtdLoc); + + String uri = "http://foo.com/bar/blah.xml"; + String uriLoc = "src/etc/testcases/taskdefs/optional/xml/about.xml"; + + DTDLocation entity = new DTDLocation(); + entity.setPublicId(uri); + entity.setLocation(uriLoc); + catalog.addEntity(entity); + File xmlFile = project.resolveFile(uriLoc); + + XMLCatalog catalog1 = newCatalog(); + catalog1.addConfiguredXMLCatalog(catalog); + + try { + InputSource result = catalog1.resolveEntity(publicId, + "nap:chemical+brothers"); + assertNotNull(result); + assertEquals(toURLString(dtdFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + try { + Source result = catalog.resolve(uri, null); + assertNotNull(result); + assertEquals(toURLString(xmlFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + + } + + public void testResolverBase() { + + String uri = "http://foo.com/bar/blah.xml"; + String uriLoc = "etc/testcases/taskdefs/optional/xml/about.xml"; + String base = null; + try { + base = toURLString(project.getBaseDir()) + "src/"; + } catch (MalformedURLException ex) { + fail (ex.toString()); + } + + DTDLocation entity = new DTDLocation(); + entity.setPublicId(uri); + entity.setLocation(uriLoc); + catalog.addEntity(entity); + File xmlFile = project.resolveFile("src/" + uriLoc); + + try { + Source result = catalog.resolve(uri, base); + assertNotNull(result); + assertEquals(toURLString(xmlFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + } + + public void testClasspath() { + + + String publicId = "-//stevo//DTD doc 1.0//EN"; + String dtdLoc = "testcases/taskdefs/optional/xml/doc.dtd"; + String path1 = project.getBaseDir().toString() + "/src/etc"; + + DTDLocation dtd = new DTDLocation(); + dtd.setPublicId(publicId); + dtd.setLocation(dtdLoc); + catalog.addDTD(dtd); + File dtdFile = project.resolveFile("src/etc/" + dtdLoc); + + String uri = "http://foo.com/bar/blah.xml"; + String uriLoc = "etc/testcases/taskdefs/optional/xml/about.xml"; + String path2 = project.getBaseDir().toString() + "/src"; + + DTDLocation entity = new DTDLocation(); + entity.setPublicId(uri); + entity.setLocation(uriLoc); + catalog.addEntity(entity); + File xmlFile = project.resolveFile("src/" + uriLoc); + + Path aPath = new Path(project, path1); + aPath.append(new Path(project, path2)); + catalog.setClasspath(aPath); + + try { + InputSource result = catalog.resolveEntity(publicId, + "nap:chemical+brothers"); + assertNotNull(result); + assertEquals(toURLString(dtdFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolveEntity() failed!" + e.toString()); + } + + try { + Source result = catalog.resolve(uri, null); + assertNotNull(result); + assertEquals(toURLString(xmlFile), + result.getSystemId()); + } catch (Exception e) { + fail("resolve() failed!" + e.toString()); + } + } +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/BaseSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/BaseSelectorTest.java new file mode 100644 index 000000000..9cda505e1 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/BaseSelectorTest.java @@ -0,0 +1,192 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.BuildFileTest; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +import java.io.File; + +/** + * Base test case for Selectors. Provides a shared test as well as + * a test bed for selecting on, and a helper method for determining + * whether selections are correct. + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public abstract class BaseSelectorTest extends TestCase { + + private Project project; + private TaskdefForMakingBed tbed = null; + protected String basedirname = "src/etc/testcases/types/selectortest"; + protected File basedir = new File(basedirname); + protected String[] filenames = {".","asf-logo.gif.md5","asf-logo.gif.bz2", + "asf-logo.gif.gz","copy.filterset.filtered","zip/asf-logo.gif.zip", + "tar/asf-logo.gif.tar","tar/asf-logo-huge.tar", + "tar/gz/asf-logo.gif.tar.gz","tar/bz2/asf-logo.gif.tar.bz2", + "tar/bz2/asf-logo-huge.tar.bz2","tar/bz2"}; + protected File[] files = new File[filenames.length]; + + public BaseSelectorTest(String name) { + super(name); + } + + public void setUp() { + project = new Project(); + project.setBasedir("."); + for (int x = 0; x < files.length; x++) { + files[x] = new File(basedir,filenames[x]); + } + } + + /** + * Override this in child classes to return a specific Selector + */ + public abstract BaseSelector getInstance(); + + + /** + * This is a test that all Selectors derived from BaseSelector can + * use. It calls the setError() method and checks to ensure that a + * BuildException is thrown as a result. + */ + public void testRespondsToError() { + BaseSelector s = getInstance(); + if (s == null) { + return; + } + s.setError("test error"); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("Cannot cause BuildException when setError() is called"); + } catch (BuildException be) { + assertEquals("test error", + be.getMessage()); + } + } + + + /** + * This is a helper method that takes a selector and calls its + * isSelected() method on each file in the testbed. It returns + * a string of "T"s amd "F"s + */ + public String selectionString(FileSelector selector) { + StringBuffer buf = new StringBuffer(); + for (int x = 0; x < files.length; x++) { + if (selector.isSelected(basedir,filenames[x],files[x])) { + buf.append('T'); + } + else { + buf.append('F'); + } + } + return buf.toString(); + } + + /** + * <p>Creates a testbed. We avoid the dreaded "test" word so that we + * don't falsely identify this as a test to be run. The actual + * setting up of the testbed is done in the + * <code>src/etc/testcases/types/selectors.xml</code> build file.</p> + * + * <p>Note that the right way to call this is within a try block, + * with a finally clause that calls cleanupBed(). You place tests of + * the isSelected() method within the try block.</p> + */ + protected void makeBed() { + tbed = new TaskdefForMakingBed("setupfiles"); + tbed.setUp(); + tbed.makeTestbed(); + } + + /** + * Cleans up the testbed by calling a target in the + * <code>src/etc/testcases/types/selectors.xml</code> file. + */ + protected void cleanupBed() { + if (tbed != null) { + tbed.tearDown(); + tbed = null; + } + } + + + private class TaskdefForMakingBed extends BuildFileTest { + + TaskdefForMakingBed(String name) { + super(name); + } + + public void setUp() { + configureProject("src/etc/testcases/types/selectors.xml"); + } + + public void tearDown() { + executeTarget("cleanup"); + } + + public void makeTestbed() { + executeTarget("setupfiles"); + } + } + + + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java new file mode 100644 index 000000000..e7b670a7c --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java @@ -0,0 +1,153 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Parameter; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Contains Selectors. + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class ContainsSelectorTest extends BaseSelectorTest { + + private Project project; + + public ContainsSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new ContainsSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + ContainsSelector s = (ContainsSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("ContainsSelector did not check for required field 'text'"); + } catch (BuildException be1) { + assertEquals("The text attribute is required", be1.getMessage()); + } + + s = (ContainsSelector)getInstance(); + Parameter param = new Parameter(); + param.setName("garbage in"); + param.setValue("garbage out"); + Parameter[] params = {param}; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("ContainsSelector did not check for valid parameter element"); + } catch (BuildException be2) { + assertEquals("Invalid parameter garbage in", be2.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + ContainsSelector s; + String results; + + try { + makeBed(); + + s = (ContainsSelector)getInstance(); + s.setText("no such string in test files"); + results = selectionString(s); + assertEquals("TFFFFFFFFFFT", results); + + s = (ContainsSelector)getInstance(); + s.setText("Apache Ant"); + results = selectionString(s); + assertEquals("TFFFTFFFFFFT", results); + + s = (ContainsSelector)getInstance(); + s.setText("apache ant"); + s.setCasesensitive(true); + results = selectionString(s); + assertEquals("TFFFFFFFFFFT", results); + + s = (ContainsSelector)getInstance(); + s.setText("apache ant"); + s.setCasesensitive(false); + results = selectionString(s); + assertEquals("TFFFTFFFFFFT", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/DateSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/DateSelectorTest.java new file mode 100644 index 000000000..e61d887a9 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/DateSelectorTest.java @@ -0,0 +1,265 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Parameter; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Date Selectors. + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class DateSelectorTest extends BaseSelectorTest { + + private Project project; + + public DateSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new DateSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + DateSelector s = (DateSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for required fields"); + } catch (BuildException be1) { + assertEquals("You must provide a datetime or the number of " + + "milliseconds.", be1.getMessage()); + } + + s = (DateSelector)getInstance(); + s.setDatetime("01/01/1969 01:01 AM"); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for Datetime being in the " + + "allowable range"); + } catch (BuildException be2) { + assertEquals("Date of 01/01/1969 01:01 AM results in negative " + + "milliseconds value relative to epoch (January 1, " + + "1970, 00:00:00 GMT).", be2.getMessage()); + } + + s = (DateSelector)getInstance(); + s.setDatetime("this is not a date"); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for Datetime being in a " + + "valid format"); + } catch (BuildException be3) { + assertEquals("Date of this is not a date" + + " Cannot be parsed correctly. It should be in" + + " MM/DD/YYYY HH:MM AM_PM format.", be3.getMessage()); + } + + s = (DateSelector)getInstance(); + Parameter param = new Parameter(); + param.setName("garbage in"); + param.setValue("garbage out"); + Parameter[] params = new Parameter[1]; + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for valid parameter element"); + } catch (BuildException be4) { + assertEquals("Invalid parameter garbage in", be4.getMessage()); + } + + s = (DateSelector)getInstance(); + param = new Parameter(); + param.setName("millis"); + param.setValue("garbage out"); + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for valid millis parameter"); + } catch (BuildException be5) { + assertEquals("Invalid millisecond setting garbage out", + be5.getMessage()); + } + + s = (DateSelector)getInstance(); + param = new Parameter(); + param.setName("granularity"); + param.setValue("garbage out"); + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DateSelector did not check for valid granularity parameter"); + } catch (BuildException be6) { + assertEquals("Invalid granularity setting garbage out", + be6.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + DateSelector s; + String results; + + DateSelector.TimeComparisons before = new + DateSelector.TimeComparisons(); + before.setValue("before"); + DateSelector.TimeComparisons equal = new + DateSelector.TimeComparisons(); + equal.setValue("equal"); + DateSelector.TimeComparisons after = new + DateSelector.TimeComparisons(); + after.setValue("after"); + + try { + makeBed(); + + s = (DateSelector)getInstance(); + s.setDatetime("10/10/1999 1:45 PM"); + s.setWhen(before); + results = selectionString(s); + assertEquals("TFFFFFFFFFFT", results); + + s = (DateSelector)getInstance(); + s.setDatetime("10/10/1999 1:45 PM"); + s.setWhen(before); + s.setCheckdirs(true); + results = selectionString(s); + assertEquals("FFFFFFFFFFFF", results); + + s = (DateSelector)getInstance(); + s.setDatetime("10/10/1999 1:45 PM"); + s.setWhen(after); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (DateSelector)getInstance(); + s.setDatetime("11/21/2001 4:54 AM"); + s.setWhen(before); + results = selectionString(s); + assertEquals("TFTFFFFFFFFT", results); +/* + s = (DateSelector)getInstance(); + s.setDatetime("11/21/2001 4:55 AM"); + java.util.Date d = new java.util.Date("11/21/2001 4:55 AM"); + long milliseconds = s.getMillis(); + s.setWhen(equal); + results = selectionString(s); + assertEquals("TTFFTFFFTTTT", results); + + s = (DateSelector)getInstance(); + s.setMillis(1006347300000L); + s.setWhen(equal); + results = selectionString(s); + assertEquals("TTFFTFFFTTTT", results); + + s = (DateSelector)getInstance(); + s.setMillis(milliseconds); + s.setWhen(equal); + results = selectionString(s); + assertEquals("TTFFTFFFTTTT", results); + + s = (DateSelector)getInstance(); + s.setMillis(1006347305000L); + s.setWhen(equal); + s.setGranularity(15000); + results = selectionString(s); + assertEquals("TTFFTFFFTTTT", results); +*/ + s = (DateSelector)getInstance(); + s.setDatetime("11/21/2001 4:56 AM"); + s.setWhen(after); + results = selectionString(s); + assertEquals("TFFTFTTTFFFT", results); + + s = (DateSelector)getInstance(); + Parameter param1 = new Parameter(); + Parameter param2 = new Parameter(); + param1.setName("datetime"); + param1.setValue("11/21/2001 4:56 AM"); + param2.setName("when"); + param2.setValue("after"); + Parameter[] params = {param1,param2}; + s.setParameters(params); + results = selectionString(s); + assertEquals("TFFTFTTTFFFT", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/DependSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/DependSelectorTest.java new file mode 100644 index 000000000..ae4014b2f --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/DependSelectorTest.java @@ -0,0 +1,176 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Mapper; +import org.apache.tools.ant.util.FileNameMapper; +import org.apache.tools.ant.util.IdentityMapper; +import org.apache.tools.ant.util.GlobPatternMapper; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Depend Selectors + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class DependSelectorTest extends BaseSelectorTest { + + private Project project; + + public DependSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new DependSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + DependSelector s = (DependSelector)getInstance(); + try { + s.createMapper(); + s.createMapper(); + fail("DependSelector allowed more than one nested mapper."); + } catch (BuildException be1) { + assertEquals("Cannot define more than one mapper", + be1.getMessage()); + } + + s = (DependSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DependSelector did not check for required fields"); + } catch (BuildException be2) { + assertEquals("The targetdir attribute is required.", + be2.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + DependSelector s; + String results; + Mapper m; + Mapper.MapperType identity = new Mapper.MapperType(); + identity.setValue("identity"); + Mapper.MapperType glob = new Mapper.MapperType(); + glob.setValue("glob"); + Mapper.MapperType merge = new Mapper.MapperType(); + merge.setValue("merge"); + + try { + makeBed(); + + s = (DependSelector)getInstance(); + s.setTargetdir(basedirname); + results = selectionString(s); + assertEquals("FFFFFFFFFFFF", results); + + s = (DependSelector)getInstance(); + s.setTargetdir(basedirname); + m = s.createMapper(); + m.setType(identity); + results = selectionString(s); + assertEquals("FFFFFFFFFFFF", results); + + s = (DependSelector)getInstance(); + s.setTargetdir(basedirname); + m = s.createMapper(); + m.setType(merge); + m.setTo("asf-logo.gif.gz"); + results = selectionString(s); + assertEquals("TFFFFTTTFFFF", results); + + s = (DependSelector)getInstance(); + s.setTargetdir(basedirname); + m = s.createMapper(); + m.setType(merge); + m.setTo("asf-logo.gif.bz2"); + results = selectionString(s); + assertEquals("TTFTTTTTTTTT", results); + + s = (DependSelector)getInstance(); + s.setTargetdir(basedirname + "/tar/bz2"); + m = s.createMapper(); + m.setType(glob); + m.setFrom("*.bz2"); + m.setTo("*.tar.bz2"); + results = selectionString(s); + assertEquals("FFFFFFFFFTTF", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/DepthSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/DepthSelectorTest.java new file mode 100644 index 000000000..621ca3c90 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/DepthSelectorTest.java @@ -0,0 +1,200 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Parameter; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Depth Selectors + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class DepthSelectorTest extends BaseSelectorTest { + + private Project project; + + public DepthSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new DepthSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + DepthSelector s = (DepthSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DepthSelector did not check for required fields"); + } catch (BuildException be1) { + assertEquals("You must set at least one of the min or the " + + "max levels.", be1.getMessage()); + } + + s = (DepthSelector)getInstance(); + s.setMin(5); + s.setMax(2); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DepthSelector did not check for maximum being higher " + + "than minimum"); + } catch (BuildException be2) { + assertEquals("The maximum depth is lower than the minimum.", + be2.getMessage()); + } + + s = (DepthSelector)getInstance(); + Parameter param = new Parameter(); + param.setName("garbage in"); + param.setValue("garbage out"); + Parameter[] params = new Parameter[1]; + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DepthSelector did not check for valid parameter element"); + } catch (BuildException be3) { + assertEquals("Invalid parameter garbage in", be3.getMessage()); + } + + s = (DepthSelector)getInstance(); + param = new Parameter(); + param.setName("min"); + param.setValue("garbage out"); + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DepthSelector accepted bad minimum as parameter"); + } catch (BuildException be4) { + assertEquals("Invalid minimum value garbage out", + be4.getMessage()); + } + + s = (DepthSelector)getInstance(); + param = new Parameter(); + param.setName("max"); + param.setValue("garbage out"); + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("DepthSelector accepted bad maximum as parameter"); + } catch (BuildException be5) { + assertEquals("Invalid maximum value garbage out", + be5.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + DepthSelector s; + String results; + + try { + makeBed(); + + s = (DepthSelector)getInstance(); + s.setMin(20); + s.setMax(25); + results = selectionString(s); + assertEquals("FFFFFFFFFFFF", results); + + s = (DepthSelector)getInstance(); + s.setMin(0); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (DepthSelector)getInstance(); + s.setMin(1); + results = selectionString(s); + assertEquals("FFFFFTTTTTTT", results); + + s = (DepthSelector)getInstance(); + s.setMax(0); + results = selectionString(s); + assertEquals("TTTTTFFFFFFF", results); + + s = (DepthSelector)getInstance(); + s.setMin(1); + s.setMax(1); + results = selectionString(s); + assertEquals("FFFFFTTTFFFT", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java new file mode 100644 index 000000000..c60969290 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java @@ -0,0 +1,167 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Parameter; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Filename Selectors + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class FilenameSelectorTest extends BaseSelectorTest { + + private Project project; + + public FilenameSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new FilenameSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + FilenameSelector s = (FilenameSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("FilenameSelector did not check for required fields"); + } catch (BuildException be1) { + assertEquals("The name attribute is required", be1.getMessage()); + } + + s = (FilenameSelector)getInstance(); + Parameter param = new Parameter(); + param.setName("garbage in"); + param.setValue("garbage out"); + Parameter[] params = {param}; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("FilenameSelector did not check for valid parameter element"); + } catch (BuildException be2) { + assertEquals("Invalid parameter garbage in", be2.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + FilenameSelector s; + String results; + + try { + makeBed(); + + s = (FilenameSelector)getInstance(); + s.setName("no match possible"); + results = selectionString(s); + assertEquals("FFFFFFFFFFFF", results); + + s = (FilenameSelector)getInstance(); + s.setName("*.gz"); + results = selectionString(s); + // This is turned off temporarily. There appears to be a bug + // in SelectorUtils.matchPattern() where it is recursive on + // Windows even if no ** is in pattern. + //assertEquals("FFFTFFFFFFFF", results); // Unix + // vs + //assertEquals("FFFTFFFFTFFF", results); // Windows + + s = (FilenameSelector)getInstance(); + s.setName("**/*.gz"); + s.setNegate(true); + results = selectionString(s); + assertEquals("TTTFTTTTFTTT", results); + + s = (FilenameSelector)getInstance(); + s.setName("**/*.GZ"); + s.setCasesensitive(false); + results = selectionString(s); + assertEquals("FFFTFFFFTFFF", results); + + s = (FilenameSelector)getInstance(); + Parameter param1 = new Parameter(); + param1.setName("name"); + param1.setValue("**/*.bz2"); + Parameter[] params = {param1}; + s.setParameters(params); + results = selectionString(s); + assertEquals("FFTFFFFFFTTF", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/PresentSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/PresentSelectorTest.java new file mode 100644 index 000000000..eea20975f --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/PresentSelectorTest.java @@ -0,0 +1,177 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Mapper; +import org.apache.tools.ant.util.FileNameMapper; +import org.apache.tools.ant.util.IdentityMapper; +import org.apache.tools.ant.util.GlobPatternMapper; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Present Selectors + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class PresentSelectorTest extends BaseSelectorTest { + + private Project project; + + public PresentSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new PresentSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + PresentSelector s = (PresentSelector)getInstance(); + try { + s.createMapper(); + s.createMapper(); + fail("PresentSelector allowed more than one nested mapper."); + } catch (BuildException be1) { + assertEquals("Cannot define more than one mapper", + be1.getMessage()); + } + + s = (PresentSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("PresentSelector did not check for required fields"); + } catch (BuildException be2) { + assertEquals("The targetdir attribute is required.", + be2.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + PresentSelector s; + String results; + Mapper m; + Mapper.MapperType identity = new Mapper.MapperType(); + identity.setValue("identity"); + Mapper.MapperType glob = new Mapper.MapperType(); + glob.setValue("glob"); + Mapper.MapperType merge = new Mapper.MapperType(); + merge.setValue("merge"); + Mapper.MapperType flatten = new Mapper.MapperType(); + flatten.setValue("flatten"); + + try { + makeBed(); + + s = (PresentSelector)getInstance(); + s.setTargetdir(basedirname); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (PresentSelector)getInstance(); + s.setTargetdir(basedirname); + m = s.createMapper(); + m.setType(identity); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (PresentSelector)getInstance(); + s.setTargetdir("src/etc/testcases/taskdefs/expected"); + m = s.createMapper(); + m.setType(flatten); + results = selectionString(s); + assertEquals("TTTTTTTTTTTF", results); + + s = (PresentSelector)getInstance(); + s.setTargetdir(basedirname); + m = s.createMapper(); + m.setType(merge); + m.setTo("asf-logo.gif.gz"); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (PresentSelector)getInstance(); + s.setTargetdir(basedirname + "/tar/bz2"); + m = s.createMapper(); + m.setType(glob); + m.setFrom("*.bz2"); + m.setTo("*.tar.bz2"); + results = selectionString(s); + assertEquals("FFTFFFFFFFFF", results); + + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/types/selectors/SizeSelectorTest.java b/src/testcases/org/apache/tools/ant/types/selectors/SizeSelectorTest.java new file mode 100644 index 000000000..be471e5ba --- /dev/null +++ b/src/testcases/org/apache/tools/ant/types/selectors/SizeSelectorTest.java @@ -0,0 +1,243 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 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.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.util.*; +import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.types.Parameter; + +import junit.framework.TestCase; +import junit.framework.AssertionFailedError; + +/** + * Tests Size Selectors + * + * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a> + */ +public class SizeSelectorTest extends BaseSelectorTest { + + private Project project; + + public SizeSelectorTest(String name) { + super(name); + } + + /** + * Factory method from base class. This is overriden in child + * classes to return a specific Selector class. + */ + public BaseSelector getInstance() { + return new SizeSelector(); + } + + /** + * Test the code that validates the selector. + */ + public void testValidate() { + SizeSelector s = (SizeSelector)getInstance(); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("SizeSelector did not check for required fields"); + } catch (BuildException be1) { + assertEquals("The value attribute is required, and must " + + "be positive", be1.getMessage()); + } + + s = (SizeSelector)getInstance(); + s.setValue(-10); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("SizeSelector did not check for value being in the " + + "allowable range"); + } catch (BuildException be2) { + assertEquals("The value attribute is required, and must " + + "be positive", be2.getMessage()); + } + + s = (SizeSelector)getInstance(); + Parameter param = new Parameter(); + param.setName("garbage in"); + param.setValue("garbage out"); + Parameter[] params = {param}; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("SizeSelector did not check for valid parameter element"); + } catch (BuildException be3) { + assertEquals("Invalid parameter garbage in", be3.getMessage()); + } + + s = (SizeSelector)getInstance(); + param = new Parameter(); + param.setName("value"); + param.setValue("garbage out"); + params[0] = param; + s.setParameters(params); + try { + s.isSelected(basedir,filenames[0],files[0]); + fail("SizeSelector accepted bad value as parameter"); + } catch (BuildException be4) { + assertEquals("Invalid size setting garbage out", + be4.getMessage()); + } + + s = (SizeSelector)getInstance(); + Parameter param1 = new Parameter(); + Parameter param2 = new Parameter(); + param1.setName("value"); + param1.setValue("5"); + param2.setName("units"); + param2.setValue("garbage out"); + params = new Parameter[2]; + params[0] = param1; + params[1] = param2; + try { + s.setParameters(params); + s.isSelected(basedir,filenames[0],files[0]); + fail("SizeSelector accepted bad units as parameter"); + } catch (BuildException be5) { + assertEquals("garbage out is not a legal value for this attribute", + be5.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + public void testSelectionBehaviour() { + SizeSelector s; + String results; + + SizeSelector.ByteUnits kilo = new SizeSelector.ByteUnits(); + kilo.setValue("K"); + SizeSelector.ByteUnits kibi = new SizeSelector.ByteUnits(); + kibi.setValue("Ki"); + SizeSelector.ByteUnits tibi = new SizeSelector.ByteUnits(); + tibi.setValue("Ti"); + SizeSelector.SizeComparisons less = new SizeSelector.SizeComparisons(); + less.setValue("less"); + SizeSelector.SizeComparisons equal = new SizeSelector.SizeComparisons(); + equal.setValue("equal"); + SizeSelector.SizeComparisons more = new SizeSelector.SizeComparisons(); + more.setValue("more"); + + + try { + makeBed(); + + s = (SizeSelector)getInstance(); + s.setValue(10); + s.setWhen(less); + results = selectionString(s); + assertEquals("TFFFFFFFFFFT", results); + + s = (SizeSelector)getInstance(); + s.setValue(10); + s.setWhen(more); + results = selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = (SizeSelector)getInstance(); + s.setValue(32); + s.setWhen(equal); + results = selectionString(s); + assertEquals("TTFFTFFFFFFT", results); + + s = (SizeSelector)getInstance(); + s.setValue(7); + s.setWhen(more); + s.setUnits(kilo); + results = selectionString(s); + assertEquals("TFTFFTTTTTTT", results); + + s = (SizeSelector)getInstance(); + s.setValue(7); + s.setWhen(more); + s.setUnits(kibi); + results = selectionString(s); + assertEquals("TFTFFFTTFTTT", results); + + s = (SizeSelector)getInstance(); + s.setValue(99999); + s.setWhen(more); + s.setUnits(tibi); + results = selectionString(s); + assertEquals("TFFFFFFFFFFT", results); + + s = (SizeSelector)getInstance(); + Parameter param1 = new Parameter(); + Parameter param2 = new Parameter(); + Parameter param3 = new Parameter(); + param1.setName("value"); + param1.setValue("20"); + param2.setName("units"); + param2.setValue("Ki"); + param3.setName("when"); + param3.setValue("more"); + Parameter[] params = {param1,param2,param3}; + s.setParameters(params); + results = selectionString(s); + assertEquals("TFFFFFFTFFTT", results); + } + finally { + cleanupBed(); + } + + } + +} diff --git a/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java b/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java index 66dbaf5d2..ad0fe140b 100644 --- a/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java +++ b/src/testcases/org/apache/tools/ant/util/FileUtilsTest.java @@ -383,6 +383,30 @@ public class FileUtilsTest extends TestCase { } /** + * Test removeLeadingPath. + */ + public void testRemoveLeadingPath() { + assertEquals("bar", fu.removeLeadingPath(new File("/foo"), + new File("/foo/bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("/foo/"), + new File("/foo/bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("\\foo"), + new File("\\foo\\bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("\\foo\\"), + new File("\\foo\\bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("c:/foo"), + new File("c:/foo/bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("c:/foo/"), + new File("c:/foo/bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("c:\\foo"), + new File("c:\\foo\\bar"))); + assertEquals("bar", fu.removeLeadingPath(new File("c:\\foo\\"), + new File("c:\\foo\\bar"))); + assertEquals(fu.normalize("/bar").getAbsolutePath(), + fu.removeLeadingPath(new File("/foo"), new File("/bar"))); + } + + /** * adapt file separators to local conventions */ private String localize(String path) { diff --git a/src/testcases/org/apache/tools/ant/util/JavaEnvUtilsTest.java b/src/testcases/org/apache/tools/ant/util/JavaEnvUtilsTest.java index b649809c3..adac16dc5 100644 --- a/src/testcases/org/apache/tools/ant/util/JavaEnvUtilsTest.java +++ b/src/testcases/org/apache/tools/ant/util/JavaEnvUtilsTest.java @@ -155,7 +155,8 @@ public class JavaEnvUtilsTest extends TestCase { j.startsWith(javaHomeParent)); if (JavaEnvUtils.getJavaVersion() == JavaEnvUtils.JAVA_1_0 || - JavaEnvUtils.getJavaVersion() == JavaEnvUtils.JAVA_1_1) { + JavaEnvUtils.getJavaVersion() == JavaEnvUtils.JAVA_1_1 || + Os.isFamily("mac")) { assertTrue(j+" is normalized and in the JRE dir", j.startsWith(javaHome)); } else { |