git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@348500 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -163,6 +163,9 @@ Fixed bugs: | |||||
| Other changes: | Other changes: | ||||
| -------------- | -------------- | ||||
| * New task <manifestclasspath> converts a path into a property | |||||
| suitable as the value for a manifest's Class-Path attribute. | |||||
| * Fixed references to obsoleted CVS web site. Bugzilla Report 36854. | * Fixed references to obsoleted CVS web site. Bugzilla Report 36854. | ||||
| * Log fine-grained events at verbose level from JUnit. Bugzilla report 31885. | * Log fine-grained events at verbose level from JUnit. Bugzilla report 31885. | ||||
| @@ -0,0 +1,98 @@ | |||||
| <html> | |||||
| <head> | |||||
| <meta http-equiv="Content-Language" content="en-us"> | |||||
| <link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||||
| <title>ManifestClassPath Task</title> | |||||
| </head> | |||||
| <body> | |||||
| <h2><a name="manifestclasspath">Manifestclasspath</a></h2> | |||||
| <h3>Description</h3> | |||||
| <p>Converts a <a href="../using.html#path">Path</a> into a property | |||||
| whose value is appropriate for a <a href="manifest.html">Manifest</a>'s | |||||
| <code>Class-Path</code> attribute.</p> | |||||
| <p>This task is often used to work around command line limitations on Windows | |||||
| when using very long class paths when launching an application. The long class | |||||
| path normally specified on the command line is replaced by a single (possibly | |||||
| empty) jar file which an in-manifest Class-Path attribute whose value lists | |||||
| all the jar and zip files the class path should contain. The files referenced | |||||
| from this attribute must be found relatively to the jar file itself, usually | |||||
| in the same directory. The Java VM automically uses all file entries listed | |||||
| in the Class-Path attributes of a jar to locate/load classes. Note though that | |||||
| it silently ignores entries for which it cannot find any corresponding file.</p> | |||||
| <p>Note that the property value created may be longer than a manifest's maximum | |||||
| 72 characters per line, but will be properly wrapped as per the Jar | |||||
| specification by the <code><manifest></code> element, where the | |||||
| defined property is re-referenced.</p> | |||||
| <p><em>since Ant 1.7</em></p> | |||||
| <h3>Parameters</h3> | |||||
| <table border="1" cellpadding="2" cellspacing="0"> | |||||
| <tr> | |||||
| <td valign="top"><b>Attribute</b></td> | |||||
| <td valign="top"><b>Description</b></td> | |||||
| <td align="center" valign="top"><b>Required</b></td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">property</td> | |||||
| <td valign="top">the name of the property to set. This property must | |||||
| not already be set.</td> | |||||
| <td valign="top" align="center">Yes</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">jarfile</td> | |||||
| <td valign="top"> | |||||
| the filename for the Jar which will contain the manifest that will | |||||
| use the property this task will set. This file need not exist yet, | |||||
| but its parent directory must exist. | |||||
| </td> | |||||
| <td valign="top" align="center">Yes</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">maxParentLevels</td> | |||||
| <td valign="top"> | |||||
| The maximum number of parent directories one is allowed to traverse | |||||
| to navigate from the jar file to the path entry. Put differently, the | |||||
| maximum number of .. which is allowed in the relative path from the | |||||
| jar file to a given class path enty. Specify 0 to enforce a path | |||||
| entry to be in the same directory (or one of its sub-directories) | |||||
| as the jar file itself. Defaults to 2 levels.</td> | |||||
| <td valign="top" align="center">No</td> | |||||
| </tr> | |||||
| </table> | |||||
| <h3>Parameters specified as nested elements</h3> | |||||
| <h4>classpath</h4> | |||||
| <p>A <a href="../using#path.html">Path-like</a> element, which can be | |||||
| defined in-place, or refer to a path defined elsewhere using the | |||||
| <code><classpath refid="<em>pathid</em>" /></code> syntax. | |||||
| This classpath must not be empty, and is required.</p> | |||||
| <h3>Examples</h3> | |||||
| <div id="example1"> | |||||
| <blockquote><pre> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="build/acme.jar"> | |||||
| <classpath refid="classpath" /> | |||||
| </manifestclasspath> | |||||
| </pre></blockquote> | |||||
| <p>Assuming a path of id "classpath" was already defined, convert this | |||||
| path relatively to the build/ directory that will contain acme.jar, which | |||||
| can later be created with <code><jar></code> with a nested | |||||
| <code><manifest></code> element that lists an | |||||
| <code><attribute name="Class-Path" value="${jar.classpath}" /></code>. | |||||
| </p> | |||||
| </div> | |||||
| <hr> | |||||
| <p align="center">Copyright © 2005 The Apache Software Foundation. | |||||
| All rights Reserved.</p> | |||||
| </body> | |||||
| </html> | |||||
| @@ -69,6 +69,7 @@ | |||||
| <a href="CoreTasks/mail.html">Mail</a><br> | <a href="CoreTasks/mail.html">Mail</a><br> | ||||
| <a href="CoreTasks/macrodef.html">MacroDef</a><br> | <a href="CoreTasks/macrodef.html">MacroDef</a><br> | ||||
| <a href="CoreTasks/manifest.html">Manifest</a><br> | <a href="CoreTasks/manifest.html">Manifest</a><br> | ||||
| <a href="CoreTasks/manifestclasspath.html">ManifestClassPath</a><br> | |||||
| <a href="CoreTasks/mkdir.html">Mkdir</a><br> | <a href="CoreTasks/mkdir.html">Mkdir</a><br> | ||||
| <a href="CoreTasks/move.html">Move</a><br> | <a href="CoreTasks/move.html">Move</a><br> | ||||
| <a href="CoreTasks/nice.html">Nice</a><br> | <a href="CoreTasks/nice.html">Nice</a><br> | ||||
| @@ -0,0 +1,164 @@ | |||||
| <?xml version="1.0"?> | |||||
| <project name="manifestclasspath" default="tearDown"> | |||||
| <target name="setUp"> | |||||
| <property name="tmp" location="${basedir}/${ant.project.name}.tmp" /> | |||||
| <mkdir dir="${tmp}" /> | |||||
| </target> | |||||
| <target name="fullSetUp" depends="setUp"> | |||||
| <mkdir dir="${tmp}/lib" /> | |||||
| <touch file="${tmp}/lib/acme-core.jar" /> | |||||
| <touch file="${tmp}/lib/acme-pres.jar" /> | |||||
| <mkdir dir="${tmp}/classes/dsp-core/com/lgc/infra/core" /> | |||||
| <mkdir dir="${tmp}/classes/dsp-pres/com/lgc/infra/pres" /> | |||||
| <mkdir dir="${tmp}/classes/dsp-void" /> | |||||
| <mkdir dir="${tmp}/generated/dsp-core/com/lgc/infra/core/generated" /> | |||||
| <mkdir dir="${tmp}/generated/dsp-pres" /> | |||||
| <mkdir dir="${tmp}/generated/dsp-void" /> | |||||
| <mkdir dir="${tmp}/resources/dsp-core/com/lgc/infra/core" /> | |||||
| <mkdir dir="${tmp}/resources/dsp-pres/com/lgc/infra/pres" /> | |||||
| <mkdir dir="${tmp}/resources/dsp-void" /> | |||||
| </target> | |||||
| <target name="tearDown"> | |||||
| <delete dir="${tmp}" /> | |||||
| </target> | |||||
| <target name="test-bad-directory"> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classpath.jar"> | |||||
| <classpath /> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-bad-no-property" depends="setUp"> | |||||
| <manifestclasspath jarfile="${tmp}/classpath.jar"> | |||||
| <classpath /> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-bad-property-exists" depends="setUp"> | |||||
| <property name="jar.classpath" value="exists" /> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classpath.jar"> | |||||
| <classpath /> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-bad-no-jarfile" depends="setUp"> | |||||
| <manifestclasspath property="jar.classpath"> | |||||
| <classpath /> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-bad-no-classpath" depends="setUp"> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classpath.jar" /> | |||||
| </target> | |||||
| <target name="test-pseudo-tahoe-refid" depends="fullSetUp"> | |||||
| <path id="classpath"> | |||||
| <!-- All the classes/ directories --> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <!-- All the JAXB generated/ directories --> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*"> | |||||
| <!-- Add only non-empty directories to the classpath --> | |||||
| <present targetdir="${tmp}/generated" present="both"> | |||||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||||
| </present> | |||||
| </dirset> | |||||
| <!-- All the resources/ directories --> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*"> | |||||
| <!-- Add only non-empty directories to the classpath --> | |||||
| <present targetdir="${tmp}/resources" present="both"> | |||||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||||
| </present> | |||||
| </dirset> | |||||
| </path> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classpath.jar"> | |||||
| <classpath refid="classpath" /> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-pseudo-tahoe-nested" depends="fullSetUp"> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classpath.jar"> | |||||
| <classpath> | |||||
| <!-- All the classes/ directories --> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <!-- All the JAXB generated/ directories --> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*"> | |||||
| <!-- Add only non-empty directories to the classpath --> | |||||
| <present targetdir="${tmp}/generated" present="both"> | |||||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||||
| </present> | |||||
| </dirset> | |||||
| <!-- All the resources/ directories --> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*"> | |||||
| <!-- Add only non-empty directories to the classpath --> | |||||
| <present targetdir="${tmp}/resources" present="both"> | |||||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||||
| </present> | |||||
| </dirset> | |||||
| </classpath> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-parent-level1" depends="fullSetUp"> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classes/classpath.jar"> | |||||
| <classpath> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||||
| </classpath> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-parent-level2" depends="fullSetUp"> | |||||
| <mkdir dir="${tmp}/classes/level2" /> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||||
| <classpath> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||||
| </classpath> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-parent-level2-too-deep" depends="fullSetUp"> | |||||
| <mkdir dir="${tmp}/classes/level2" /> | |||||
| <manifestclasspath property="jar.classpath" maxParentLevels="1" | |||||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||||
| <classpath> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||||
| </classpath> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| <target name="test-parent-level2-with-jars" depends="fullSetUp"> | |||||
| <mkdir dir="${tmp}/classes/level2" /> | |||||
| <manifestclasspath property="jar.classpath" | |||||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||||
| <classpath> | |||||
| <fileset dir="${tmp}/lib" includes="*.jar" /> | |||||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||||
| </classpath> | |||||
| </manifestclasspath> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,184 @@ | |||||
| /* | |||||
| * Copyright 2005 The Apache Software Foundation | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import java.io.File; | |||||
| import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.util.FileUtils; | |||||
| /** | |||||
| * Converts a Path into a property suitable as a Manifest classpath. | |||||
| * | |||||
| * @since Ant 1.7 | |||||
| * | |||||
| * @ant.task category="property" | |||||
| */ | |||||
| public class ManifestClassPath | |||||
| extends Task { | |||||
| /** The property name to hold the classpath value. */ | |||||
| private String _name; | |||||
| /** The directory the classpath will be relative from. */ | |||||
| private File _dir; | |||||
| /** The maximum parent directory level to traverse. */ | |||||
| private int _maxParentLevels = 2; | |||||
| /** The classpath to convert. */ | |||||
| private Path _path; | |||||
| /** | |||||
| * Sets a property, which must not already exists, with a space | |||||
| * separated list of files and directories relative to the jar | |||||
| * file's parent directory. | |||||
| */ | |||||
| public void execute() { | |||||
| if (_name == null) { | |||||
| throw new BuildException("Missing 'property' attribute!"); | |||||
| } | |||||
| if (_dir == null) { | |||||
| throw new BuildException("Missing 'jarfile' attribute!"); | |||||
| } | |||||
| if (getProject().getProperty(_name) != null) { | |||||
| throw new BuildException("Property '" + _name + "' already set!"); | |||||
| } | |||||
| if (_path == null) { | |||||
| throw new BuildException("Missing nested <classpath>!"); | |||||
| } | |||||
| // Normalize the reference directory (containing the jar) | |||||
| final FileUtils fileUtils = FileUtils.getFileUtils(); | |||||
| _dir = fileUtils.normalize(_dir.getAbsolutePath()); | |||||
| // Create as many directory prefixes as parent levels to traverse, | |||||
| // in addition to the reference directory itself | |||||
| File currDir = _dir; | |||||
| String[] dirs = new String[_maxParentLevels + 1]; | |||||
| for (int i = 0; i < _maxParentLevels + 1; ++i) { | |||||
| dirs[i] = currDir.getAbsolutePath() + File.separatorChar; | |||||
| currDir = currDir.getParentFile(); | |||||
| if (currDir == null) { | |||||
| _maxParentLevels = i + 1; | |||||
| break; | |||||
| } | |||||
| } | |||||
| String[] elements = _path.list(); | |||||
| StringBuffer buffer = new StringBuffer(); | |||||
| StringBuffer element = new StringBuffer(); | |||||
| for (int i = 0; i < elements.length; ++i) { | |||||
| // Normalize the current file | |||||
| File pathEntry = new File(elements[i]); | |||||
| pathEntry = fileUtils.normalize(pathEntry.getAbsolutePath()); | |||||
| String fullPath = pathEntry.getAbsolutePath(); | |||||
| // Find the longest prefix shared by the current file | |||||
| // and the reference directory. | |||||
| String relPath = null; | |||||
| for (int j = 0; j <= _maxParentLevels; ++j) { | |||||
| String dir = dirs[j]; | |||||
| if (!fullPath.startsWith(dir)) { | |||||
| continue; | |||||
| } | |||||
| // We have a match! Add as many ../ as parent | |||||
| // directory traversed to get the relative path | |||||
| element.setLength(0); | |||||
| for (int k = 0; k < j; ++k) { | |||||
| element.append(".."); | |||||
| element.append(File.separatorChar); | |||||
| } | |||||
| element.append(fullPath.substring(dir.length())); | |||||
| relPath = element.toString(); | |||||
| break; | |||||
| } | |||||
| // No match, so bail out! | |||||
| if (relPath == null) { | |||||
| throw new BuildException("No suitable relative path from " + | |||||
| _dir + " to " + fullPath); | |||||
| } | |||||
| // Manifest's ClassPath: attribute always uses forward | |||||
| // slashes '/', and is space-separated. Ant will properly | |||||
| // format it on 72 columns with proper line continuation | |||||
| if (File.separatorChar != '/') { | |||||
| relPath = relPath.replace(File.separatorChar, '/'); | |||||
| } | |||||
| buffer.append(relPath); | |||||
| if (pathEntry.isDirectory()) { | |||||
| buffer.append('/'); | |||||
| } | |||||
| buffer.append(' '); | |||||
| } | |||||
| // Get rid of trailing space, if any | |||||
| if (buffer.length() > 0) { | |||||
| buffer.setLength(buffer.length() - 1); | |||||
| } | |||||
| // Finally assign the property with the manifest classpath | |||||
| getProject().setNewProperty(_name, buffer.toString()); | |||||
| } | |||||
| /** | |||||
| * Sets the property name to hold the classpath value. | |||||
| * | |||||
| * @param name the property name | |||||
| */ | |||||
| public void setProperty(String name) { | |||||
| _name = name; | |||||
| } | |||||
| /** | |||||
| * The JAR file to contain the classpath attribute in its manifest. | |||||
| * | |||||
| * @param jarfile the JAR file. Need not exist yet, but its parent | |||||
| * directory must exist on the other hand. | |||||
| */ | |||||
| public void setJarFile(File jarfile) { | |||||
| File parent = jarfile.getParentFile(); | |||||
| if (!parent.isDirectory()) { | |||||
| throw new BuildException("Jar's directory not found: " + parent); | |||||
| } | |||||
| _dir = parent; | |||||
| } | |||||
| /** | |||||
| * Sets the maximum parent directory levels allowed when computing | |||||
| * a relative path. | |||||
| * | |||||
| * @param levels the max level. Defaults to 2. | |||||
| */ | |||||
| public void setMaxParentLevels(int levels) { | |||||
| _maxParentLevels = levels; | |||||
| } | |||||
| /** | |||||
| * Adds the classpath to convert. | |||||
| * | |||||
| * @param path the classpath to convert. | |||||
| */ | |||||
| public void addClassPath(Path path) { | |||||
| _path = path; | |||||
| } | |||||
| } | |||||
| @@ -47,6 +47,7 @@ loadproperties=org.apache.tools.ant.taskdefs.LoadProperties | |||||
| macrodef=org.apache.tools.ant.taskdefs.MacroDef | macrodef=org.apache.tools.ant.taskdefs.MacroDef | ||||
| mail=org.apache.tools.ant.taskdefs.email.EmailTask | mail=org.apache.tools.ant.taskdefs.email.EmailTask | ||||
| manifest=org.apache.tools.ant.taskdefs.ManifestTask | manifest=org.apache.tools.ant.taskdefs.ManifestTask | ||||
| manifestclasspath=org.apache.tools.ant.taskdefs.ManifestClassPath | |||||
| mkdir=org.apache.tools.ant.taskdefs.Mkdir | mkdir=org.apache.tools.ant.taskdefs.Mkdir | ||||
| move=org.apache.tools.ant.taskdefs.Move | move=org.apache.tools.ant.taskdefs.Move | ||||
| nice=org.apache.tools.ant.taskdefs.Nice | nice=org.apache.tools.ant.taskdefs.Nice | ||||
| @@ -221,4 +222,4 @@ rename=org.apache.tools.ant.taskdefs.Rename | |||||
| renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions | renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions | ||||
| starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut | starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut | ||||
| style=org.apache.tools.ant.taskdefs.XSLTProcess | style=org.apache.tools.ant.taskdefs.XSLTProcess | ||||
| WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet | |||||
| WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet | |||||
| @@ -42,19 +42,42 @@ public abstract class BuildFileTest extends TestCase { | |||||
| private BuildException buildException; | private BuildException buildException; | ||||
| /** | /** | ||||
| * Constructor for the BuildFileTest object | |||||
| * Default constructor for the BuildFileTest object. | |||||
| */ | |||||
| public BuildFileTest() { | |||||
| super(); | |||||
| } | |||||
| /** | |||||
| * Constructor for the BuildFileTest object. | |||||
| * | * | ||||
| *@param name string to pass up to TestCase constructor | |||||
| * @param name string to pass up to TestCase constructor | |||||
| */ | */ | ||||
| public BuildFileTest(String name) { | public BuildFileTest(String name) { | ||||
| super(name); | super(name); | ||||
| } | } | ||||
| /** | /** | ||||
| * run a target, expect for any build exception | |||||
| * Automatically calls the target called "tearDown" | |||||
| * from the build file tested if it exits. | |||||
| * | * | ||||
| *@param target target to run | |||||
| *@param cause information string to reader of report | |||||
| * This allows to use Ant tasks directly in the build file | |||||
| * to clean up after each test. Note that no "setUp" target | |||||
| * is automatically called, since it's trivial to have a | |||||
| * test target depend on it. | |||||
| */ | |||||
| protected void tearDown() throws Exception { | |||||
| final String tearDown = "tearDown"; | |||||
| if (project.getTargets().containsKey(tearDown)) { | |||||
| project.executeTarget(tearDown); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * run a target, expect for any build exception | |||||
| * | |||||
| * @param target target to run | |||||
| * @param cause information string to reader of report | |||||
| */ | */ | ||||
| protected void expectBuildException(String target, String cause) { | protected void expectBuildException(String target, String cause) { | ||||
| expectSpecificBuildException(target, cause, null); | expectSpecificBuildException(target, cause, null); | ||||
| @@ -71,9 +94,8 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Assert that the given substring is in the log messages | |||||
| * Assert that the given substring is in the log messages. | |||||
| */ | */ | ||||
| protected void assertLogContaining(String substring) { | protected void assertLogContaining(String substring) { | ||||
| String realLog = getLog(); | String realLog = getLog(); | ||||
| assertTrue("expecting log to contain \"" + substring + "\" log was \"" | assertTrue("expecting log to contain \"" + substring + "\" log was \"" | ||||
| @@ -82,16 +104,16 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Assert that the given substring is in the output messages | |||||
| * Assert that the given substring is in the output messages. | |||||
| * @since Ant1.7 | * @since Ant1.7 | ||||
| */ | */ | ||||
| protected void assertOutputContaining(String substring) { | protected void assertOutputContaining(String substring) { | ||||
| String realOutput = getOutput(); | String realOutput = getOutput(); | ||||
| assertTrue("expecting output to contain \"" + substring + "\" output was \"" | |||||
| + realOutput + "\"", | |||||
| realOutput.indexOf(substring) >= 0); | |||||
| assertTrue("expecting output to contain \"" + substring | |||||
| + "\" output was \"" + realOutput + "\"", | |||||
| realOutput.indexOf(substring) >= 0); | |||||
| } | } | ||||
| /** | /** | ||||
| * Assert that the given message has been logged with a priority | * Assert that the given message has been logged with a priority | ||||
| * <= INFO when running the given target. | * <= INFO when running the given target. | ||||
| @@ -102,9 +124,9 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Gets the log the BuildFileTest object. | |||||
| * only valid if configureProject() has | |||||
| * been called. | |||||
| * Gets the log the BuildFileTest object. | |||||
| * Only valid if configureProject() has been called. | |||||
| * | |||||
| * @pre logBuffer!=null | * @pre logBuffer!=null | ||||
| * @return The log value | * @return The log value | ||||
| */ | */ | ||||
| @@ -123,9 +145,8 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Assert that the given substring is in the log messages | |||||
| * Assert that the given substring is in the log messages. | |||||
| */ | */ | ||||
| protected void assertDebuglogContaining(String substring) { | protected void assertDebuglogContaining(String substring) { | ||||
| String realLog = getFullLog(); | String realLog = getFullLog(); | ||||
| assertTrue("expecting debug log to contain \"" + substring | assertTrue("expecting debug log to contain \"" + substring | ||||
| @@ -135,9 +156,10 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * Gets the log the BuildFileTest object. | |||||
| * only valid if configureProject() has | |||||
| * been called. | |||||
| * Gets the log the BuildFileTest object. | |||||
| * | |||||
| * Only valid if configureProject() has been called. | |||||
| * | |||||
| * @pre fullLogBuffer!=null | * @pre fullLogBuffer!=null | ||||
| * @return The log value | * @return The log value | ||||
| */ | */ | ||||
| @@ -146,12 +168,11 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * execute the target, verify output matches expectations | |||||
| * execute the target, verify output matches expectations | |||||
| * | * | ||||
| *@param target target to execute | |||||
| *@param output output to look for | |||||
| * @param target target to execute | |||||
| * @param output output to look for | |||||
| */ | */ | ||||
| protected void expectOutput(String target, String output) { | protected void expectOutput(String target, String output) { | ||||
| executeTarget(target); | executeTarget(target); | ||||
| String realOutput = getOutput(); | String realOutput = getOutput(); | ||||
| @@ -159,13 +180,13 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * execute the target, verify output matches expectations | |||||
| * and that we got the named error at the end | |||||
| *@param target target to execute | |||||
| *@param output output to look for | |||||
| *@param error Description of Parameter | |||||
| * Executes the target, verify output matches expectations | |||||
| * and that we got the named error at the end | |||||
| * | |||||
| * @param target target to execute | |||||
| * @param output output to look for | |||||
| * @param error Description of Parameter | |||||
| */ | */ | ||||
| protected void expectOutputAndError(String target, String output, String error) { | protected void expectOutputAndError(String target, String output, String error) { | ||||
| executeTarget(target); | executeTarget(target); | ||||
| String realOutput = getOutput(); | String realOutput = getOutput(); | ||||
| @@ -206,7 +227,7 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * set up to run the named project | |||||
| * Sets up to run the named project | |||||
| * | * | ||||
| * @param filename name of project file to run | * @param filename name of project file to run | ||||
| */ | */ | ||||
| @@ -215,7 +236,7 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * set up to run the named project | |||||
| * Sets up to run the named project | |||||
| * | * | ||||
| * @param filename name of project file to run | * @param filename name of project file to run | ||||
| */ | */ | ||||
| @@ -232,7 +253,8 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * execute a target we have set up | |||||
| * Executes a target we have set up | |||||
| * | |||||
| * @pre configureProject has been called | * @pre configureProject has been called | ||||
| * @param targetName target to run | * @param targetName target to run | ||||
| */ | */ | ||||
| @@ -269,7 +291,8 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * get the directory of the project | |||||
| * Gets the directory of the project. | |||||
| * | |||||
| * @return the base dir of the project | * @return the base dir of the project | ||||
| */ | */ | ||||
| protected File getProjectDir() { | protected File getProjectDir() { | ||||
| @@ -277,12 +300,12 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * run a target, wait for a build exception | |||||
| * Runs a target, wait for a build exception. | |||||
| * | * | ||||
| *@param target target to run | |||||
| *@param cause information string to reader of report | |||||
| *@param msg the message value of the build exception we are waiting for | |||||
| set to null for any build exception to be valid | |||||
| * @param target target to run | |||||
| * @param cause information string to reader of report | |||||
| * @param msg the message value of the build exception we are waiting | |||||
| * for set to null for any build exception to be valid | |||||
| */ | */ | ||||
| protected void expectSpecificBuildException(String target, String cause, String msg) { | protected void expectSpecificBuildException(String target, String cause, String msg) { | ||||
| try { | try { | ||||
| @@ -300,12 +323,12 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * run a target, expect an exception string | |||||
| * containing the substring we look for (case sensitive match) | |||||
| * run a target, expect an exception string | |||||
| * containing the substring we look for (case sensitive match) | |||||
| * | * | ||||
| *@param target target to run | |||||
| *@param cause information string to reader of report | |||||
| *@param contains substring of the build exception to look for | |||||
| * @param target target to run | |||||
| * @param cause information string to reader of report | |||||
| * @param contains substring of the build exception to look for | |||||
| */ | */ | ||||
| protected void expectBuildExceptionContaining(String target, String cause, String contains) { | protected void expectBuildExceptionContaining(String target, String cause, String contains) { | ||||
| try { | try { | ||||
| @@ -320,7 +343,6 @@ public abstract class BuildFileTest extends TestCase { | |||||
| fail("Should throw BuildException because: " + cause); | fail("Should throw BuildException because: " + cause); | ||||
| } | } | ||||
| /** | /** | ||||
| * call a target, verify property is as expected | * call a target, verify property is as expected | ||||
| * | * | ||||
| @@ -328,7 +350,6 @@ public abstract class BuildFileTest extends TestCase { | |||||
| * @param property property name | * @param property property name | ||||
| * @param value expected value | * @param value expected value | ||||
| */ | */ | ||||
| protected void expectPropertySet(String target, String property, String value) { | protected void expectPropertySet(String target, String property, String value) { | ||||
| executeTarget(target); | executeTarget(target); | ||||
| assertPropertyEquals(property, value); | assertPropertyEquals(property, value); | ||||
| @@ -336,6 +357,7 @@ public abstract class BuildFileTest extends TestCase { | |||||
| /** | /** | ||||
| * assert that a property equals a value; comparison is case sensitive. | * assert that a property equals a value; comparison is case sensitive. | ||||
| * | |||||
| * @param property property name | * @param property property name | ||||
| * @param value expected value | * @param value expected value | ||||
| */ | */ | ||||
| @@ -345,7 +367,8 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * assert that a property equals "true" | |||||
| * assert that a property equals "true". | |||||
| * | |||||
| * @param property property name | * @param property property name | ||||
| */ | */ | ||||
| protected void assertPropertySet(String property) { | protected void assertPropertySet(String property) { | ||||
| @@ -353,14 +376,14 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * assert that a property is null | |||||
| * assert that a property is null. | |||||
| * | |||||
| * @param property property name | * @param property property name | ||||
| */ | */ | ||||
| protected void assertPropertyUnset(String property) { | protected void assertPropertyUnset(String property) { | ||||
| assertPropertyEquals(property, null); | assertPropertyEquals(property, null); | ||||
| } | } | ||||
| /** | /** | ||||
| * call a target, verify named property is "true". | * call a target, verify named property is "true". | ||||
| * | * | ||||
| @@ -371,9 +394,9 @@ public abstract class BuildFileTest extends TestCase { | |||||
| expectPropertySet(target, property, "true"); | expectPropertySet(target, property, "true"); | ||||
| } | } | ||||
| /** | /** | ||||
| * call a target, verify property is null | |||||
| * Call a target, verify property is null. | |||||
| * | |||||
| * @param target build file target | * @param target build file target | ||||
| * @param property property name | * @param property property name | ||||
| */ | */ | ||||
| @@ -385,6 +408,7 @@ public abstract class BuildFileTest extends TestCase { | |||||
| * Retrieve a resource from the caller classloader to avoid | * Retrieve a resource from the caller classloader to avoid | ||||
| * assuming a vm working directory. The resource path must be | * assuming a vm working directory. The resource path must be | ||||
| * relative to the package name or absolute from the root path. | * relative to the package name or absolute from the root path. | ||||
| * | |||||
| * @param resource the resource to retrieve its url. | * @param resource the resource to retrieve its url. | ||||
| * @throws AssertionFailureException if resource is not found. | * @throws AssertionFailureException if resource is not found. | ||||
| */ | */ | ||||
| @@ -410,77 +434,77 @@ public abstract class BuildFileTest extends TestCase { | |||||
| } | } | ||||
| /** | /** | ||||
| * our own personal build listener | |||||
| * Our own personal build listener. | |||||
| */ | */ | ||||
| private class AntTestListener implements BuildListener { | private class AntTestListener implements BuildListener { | ||||
| private int logLevel; | private int logLevel; | ||||
| /** | /** | ||||
| * Constructs a test listener which will ignore log events | * Constructs a test listener which will ignore log events | ||||
| * above the given level | |||||
| * above the given level. | |||||
| */ | */ | ||||
| public AntTestListener(int logLevel) { | public AntTestListener(int logLevel) { | ||||
| this.logLevel = logLevel; | this.logLevel = logLevel; | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired before any targets are started. | |||||
| * Fired before any targets are started. | |||||
| */ | */ | ||||
| public void buildStarted(BuildEvent event) { | public void buildStarted(BuildEvent event) { | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired after the last target has finished. This event | |||||
| * will still be thrown if an error occurred during the build. | |||||
| * Fired after the last target has finished. This event | |||||
| * will still be thrown if an error occurred during the build. | |||||
| * | * | ||||
| * @see BuildEvent#getException() | |||||
| * @see BuildEvent#getException() | |||||
| */ | */ | ||||
| public void buildFinished(BuildEvent event) { | public void buildFinished(BuildEvent event) { | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired when a target is started. | |||||
| * Fired when a target is started. | |||||
| * | * | ||||
| * @see BuildEvent#getTarget() | |||||
| * @see BuildEvent#getTarget() | |||||
| */ | */ | ||||
| public void targetStarted(BuildEvent event) { | public void targetStarted(BuildEvent event) { | ||||
| //System.out.println("targetStarted " + event.getTarget().getName()); | //System.out.println("targetStarted " + event.getTarget().getName()); | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired when a target has finished. This event will | |||||
| * still be thrown if an error occurred during the build. | |||||
| * Fired when a target has finished. This event will | |||||
| * still be thrown if an error occurred during the build. | |||||
| * | * | ||||
| * @see BuildEvent#getException() | |||||
| * @see BuildEvent#getException() | |||||
| */ | */ | ||||
| public void targetFinished(BuildEvent event) { | public void targetFinished(BuildEvent event) { | ||||
| //System.out.println("targetFinished " + event.getTarget().getName()); | //System.out.println("targetFinished " + event.getTarget().getName()); | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired when a task is started. | |||||
| * Fired when a task is started. | |||||
| * | * | ||||
| * @see BuildEvent#getTask() | |||||
| * @see BuildEvent#getTask() | |||||
| */ | */ | ||||
| public void taskStarted(BuildEvent event) { | public void taskStarted(BuildEvent event) { | ||||
| //System.out.println("taskStarted " + event.getTask().getTaskName()); | //System.out.println("taskStarted " + event.getTask().getTaskName()); | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired when a task has finished. This event will still | |||||
| * be throw if an error occurred during the build. | |||||
| * Fired when a task has finished. This event will still | |||||
| * be throw if an error occurred during the build. | |||||
| * | * | ||||
| * @see BuildEvent#getException() | |||||
| * @see BuildEvent#getException() | |||||
| */ | */ | ||||
| public void taskFinished(BuildEvent event) { | public void taskFinished(BuildEvent event) { | ||||
| //System.out.println("taskFinished " + event.getTask().getTaskName()); | //System.out.println("taskFinished " + event.getTask().getTaskName()); | ||||
| } | } | ||||
| /** | /** | ||||
| * Fired whenever a message is logged. | |||||
| * Fired whenever a message is logged. | |||||
| * | * | ||||
| * @see BuildEvent#getMessage() | |||||
| * @see BuildEvent#getPriority() | |||||
| * @see BuildEvent#getMessage() | |||||
| * @see BuildEvent#getPriority() | |||||
| */ | */ | ||||
| public void messageLogged(BuildEvent event) { | public void messageLogged(BuildEvent event) { | ||||
| if (event.getPriority() > logLevel) { | if (event.getPriority() > logLevel) { | ||||
| @@ -494,9 +518,7 @@ public abstract class BuildFileTest extends TestCase { | |||||
| logBuffer.append(event.getMessage()); | logBuffer.append(event.getMessage()); | ||||
| } | } | ||||
| fullLogBuffer.append(event.getMessage()); | fullLogBuffer.append(event.getMessage()); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,139 @@ | |||||
| /* | |||||
| * Copyright 2000-2005 The Apache Software Foundation | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import java.io.File; | |||||
| import java.util.Map; | |||||
| import java.util.Properties; | |||||
| import org.apache.tools.ant.BuildFileTest; | |||||
| /** | |||||
| * Tests <bm:manifestclasspath>. | |||||
| */ | |||||
| public class ManifestClassPathTest | |||||
| extends BuildFileTest { | |||||
| public void setUp() { | |||||
| configureProject("src/etc/testcases/taskdefs/manifestclasspath.xml"); | |||||
| } | |||||
| public void testBadDirectory() { | |||||
| expectBuildExceptionContaining("test-bad-directory", "bad-jar-dir", | |||||
| "Jar's directory not found:"); | |||||
| assertPropertyUnset("jar.classpath"); | |||||
| } | |||||
| public void testBadNoProperty() { | |||||
| expectBuildExceptionContaining("test-bad-no-property", "no-property", | |||||
| "Missing 'property' attribute!"); | |||||
| assertPropertyUnset("jar.classpath"); | |||||
| } | |||||
| public void testBadPropertyExists() { | |||||
| expectBuildExceptionContaining("test-bad-property-exists", | |||||
| "property-exits", "Property 'jar.classpath' already set!"); | |||||
| assertPropertyEquals("jar.classpath", "exists"); | |||||
| } | |||||
| public void testBadNoJarfile() { | |||||
| expectBuildExceptionContaining("test-bad-no-jarfile", "no-jarfile", | |||||
| "Missing 'jarfile' attribute!"); | |||||
| assertPropertyUnset("jar.classpath"); | |||||
| } | |||||
| public void testBadNoClassPath() { | |||||
| expectBuildExceptionContaining("test-bad-no-classpath", "no-classpath", | |||||
| "Missing nested <classpath>!"); | |||||
| assertPropertyUnset("jar.classpath"); | |||||
| } | |||||
| public void testParentLevel1() { | |||||
| executeTarget("test-parent-level1"); | |||||
| assertPropertyEquals("jar.classpath", "dsp-core/ " + | |||||
| "dsp-pres/ " + | |||||
| "dsp-void/ " + | |||||
| "../generated/dsp-core/ " + | |||||
| "../generated/dsp-pres/ " + | |||||
| "../generated/dsp-void/ " + | |||||
| "../resources/dsp-core/ " + | |||||
| "../resources/dsp-pres/ " + | |||||
| "../resources/dsp-void/"); | |||||
| } | |||||
| public void testParentLevel2() { | |||||
| executeTarget("test-parent-level2"); | |||||
| assertPropertyEquals("jar.classpath", "../dsp-core/ " + | |||||
| "../dsp-pres/ " + | |||||
| "../dsp-void/ " + | |||||
| "../../generated/dsp-core/ " + | |||||
| "../../generated/dsp-pres/ " + | |||||
| "../../generated/dsp-void/ " + | |||||
| "../../resources/dsp-core/ " + | |||||
| "../../resources/dsp-pres/ " + | |||||
| "../../resources/dsp-void/"); | |||||
| } | |||||
| public void testParentLevel2TooDeep() { | |||||
| expectBuildExceptionContaining("test-parent-level2-too-deep", "nopath", | |||||
| "No suitable relative path from "); | |||||
| assertPropertyUnset("jar.classpath"); | |||||
| } | |||||
| public void testPseudoTahoeRefid() { | |||||
| executeTarget("test-pseudo-tahoe-refid"); | |||||
| assertPropertyEquals("jar.classpath", "classes/dsp-core/ " + | |||||
| "classes/dsp-pres/ " + | |||||
| "classes/dsp-void/ " + | |||||
| "generated/dsp-core/ " + | |||||
| "resources/dsp-core/ " + | |||||
| "resources/dsp-pres/"); | |||||
| } | |||||
| public void testPseudoTahoeNested() { | |||||
| executeTarget("test-pseudo-tahoe-nested"); | |||||
| assertPropertyEquals("jar.classpath", "classes/dsp-core/ " + | |||||
| "classes/dsp-pres/ " + | |||||
| "classes/dsp-void/ " + | |||||
| "generated/dsp-core/ " + | |||||
| "resources/dsp-core/ " + | |||||
| "resources/dsp-pres/"); | |||||
| } | |||||
| public void testParentLevel2WithJars() { | |||||
| executeTarget("test-parent-level2-with-jars"); | |||||
| assertPropertyEquals("jar.classpath", "../../lib/acme-core.jar " + | |||||
| "../../lib/acme-pres.jar " + | |||||
| "../dsp-core/ " + | |||||
| "../dsp-pres/ " + | |||||
| "../dsp-void/ " + | |||||
| "../../generated/dsp-core/ " + | |||||
| "../../generated/dsp-pres/ " + | |||||
| "../../generated/dsp-void/ " + | |||||
| "../../resources/dsp-core/ " + | |||||
| "../../resources/dsp-pres/ " + | |||||
| "../../resources/dsp-void/"); | |||||
| } | |||||
| } // END class ManifestClassPathTest | |||||