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 | |||||