git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@349639 13f79535-47bb-0310-9956-ffa450edef68master
@@ -12,7 +12,7 @@ | |||
<h3>Description</h3> | |||
<p>Signs JAR files with the <tt>jarsigner</tt> command line tool. | |||
It will take a named file in the <tt>jar</tt> attribute, and an optional | |||
<tt>destDir</tt> or <tt>signedJar</tt> attribute. Nested filesets are also | |||
<tt>destDir</tt> or <tt>signedJar</tt> attribute. Nested paths are also | |||
supported; here only an (optional) <tt>destDir</tt> is allowed. If a destination | |||
directory or explicit JAR file name is not provided, JARs are signed in place. | |||
</p> | |||
@@ -39,7 +39,7 @@ and <tt>lazy</tt> is false, the JAR is signed.</li> | |||
<tr> | |||
<td valign="top">jar</td> | |||
<td valign="top">the jar file to sign</td> | |||
<td valign="top" align="center">Yes, unless nested filesets have | |||
<td valign="top" align="center">Yes, unless nested paths have | |||
been used.</td> | |||
</tr> | |||
<tr> | |||
@@ -134,6 +134,11 @@ block</td> | |||
<td valign="top"><b>Description</b></td> | |||
<td align="center" valign="top"><b>Required</b></td> | |||
</tr> | |||
<tr> | |||
<td valign="top">path</td> | |||
<td valign="top">path of JAR files to sign. <em>since Ant 1.7</em></td> | |||
<td valign="top" align="center">No</td> | |||
</tr> | |||
<tr> | |||
<td valign="top">fileset</td> | |||
<td valign="top">fileset of JAR files to sign. </td> | |||
@@ -167,7 +172,9 @@ alias="apache-group" storepass="secret"/> | |||
alias="testonly" keystore="testkeystore" | |||
storepass="apacheant" | |||
preservelastmodified="true"> | |||
<fileset dir="dist" includes="**/*.jar" /> | |||
<path> | |||
<fileset dir="dist" includes="**/*.jar" /> | |||
</path> | |||
<flattenmapper /> | |||
</signjar> | |||
</pre></blockquote> | |||
@@ -183,7 +190,9 @@ all be copied to this directory, not to subdirectories. | |||
storepass="apacheant" | |||
lazy="true" | |||
> | |||
<fileset dir="dist" includes="**/*.jar" /> | |||
<path> | |||
<fileset dir="dist" includes="**/*.jar" /> | |||
</path> | |||
</signjar> | |||
</pre></blockquote> | |||
<p> | |||
@@ -118,6 +118,32 @@ | |||
</sign-base> | |||
</target> | |||
<target name="testPath" depends="jar"> | |||
<sign-base> | |||
<path> | |||
<fileset file="${test.jar}" /> | |||
</path> | |||
</sign-base> | |||
<assertSigned/> | |||
</target> | |||
<target name="testPathAndJar" depends="jar"> | |||
<sign-base jar="${test.jar}" lazy="true"> | |||
<path> | |||
<fileset file="${test.jar}" /> | |||
</path> | |||
</sign-base> | |||
<assertSigned/> | |||
</target> | |||
<target name="testPathAndSignedJar" depends="jar"> | |||
<sign-base signedjar="${sign.dir}/newfile.jar"> | |||
<path> | |||
<fileset file="${test.jar}" /> | |||
</path> | |||
</sign-base> | |||
</target> | |||
<target name="testSignedJar" depends="jar"> | |||
<sign signedjar="${subdirtest.jar}"/> | |||
<assertSigned jar="${subdirtest.jar}"/> | |||
@@ -139,6 +165,15 @@ | |||
<assertSigned jar="${subdirtest.jar}"/> | |||
</target> | |||
<target name="testDestDirPath" depends="jar"> | |||
<sign-base destDir="${subdir}"> | |||
<path> | |||
<fileset file="${test.jar}" /> | |||
</path> | |||
</sign-base> | |||
<assertSigned jar="${subdirtest.jar}"/> | |||
</target> | |||
<target name="testMapperNoDest" depends="jar"> | |||
<sign-base > | |||
<flattenmapper /> | |||
@@ -154,6 +189,16 @@ | |||
<assertSigned jar="${subdirtest.jar}"/> | |||
</target> | |||
<target name="testMapperPath" depends="jar"> | |||
<sign-base destDir="${subdir}"> | |||
<path> | |||
<pathelement location="${test.jar}" /> | |||
</path> | |||
<flattenmapper /> | |||
</sign-base> | |||
<assertSigned jar="${subdirtest.jar}"/> | |||
</target> | |||
<target name="testTwoMappers" depends="jar"> | |||
<sign-base destDir="${subdir}"> | |||
<fileset file="${test.jar}" /> | |||
@@ -211,6 +256,14 @@ | |||
</verify-base> | |||
</target> | |||
<target name="testVerifyPath" depends="basic"> | |||
<verify-base > | |||
<path> | |||
<pathelement location="${test.jar}" /> | |||
</path> | |||
</verify-base> | |||
</target> | |||
<target name="testVerifyNoArgs"> | |||
<verify-base /> | |||
</target> | |||
@@ -21,6 +21,7 @@ import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.util.JavaEnvUtils; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.types.RedirectorElement; | |||
import org.apache.tools.ant.types.Environment; | |||
@@ -90,6 +91,13 @@ public abstract class AbstractJarSignerTask extends Task { | |||
public static final String ERROR_NO_SOURCE = "jar must be set through jar attribute " | |||
+ "or nested filesets"; | |||
/** | |||
* Path holding all non-filesets of filesystem resources we want to sign. | |||
* | |||
* @since Ant 1.7 | |||
*/ | |||
private Path path = null; | |||
/** | |||
* Set the maximum memory to be used by the jarsigner process | |||
* | |||
@@ -181,6 +189,20 @@ public abstract class AbstractJarSignerTask extends Task { | |||
public void addSysproperty(Environment.Variable sysp) { | |||
sysProperties.addVariable(sysp); | |||
} | |||
/** | |||
* Adds a path of files to sign. | |||
* | |||
* @param a path of files to sign. | |||
* @since Ant 1.7 | |||
*/ | |||
public Path createPath() { | |||
if (path == null) { | |||
path = new Path(getProject()); | |||
} | |||
return path.createPath(); | |||
} | |||
/** | |||
* init processing logic; this is retained through our execution(s) | |||
*/ | |||
@@ -306,6 +328,7 @@ public abstract class AbstractJarSignerTask extends Task { | |||
//this lets us combine our logic for handling output directories, | |||
//mapping etc. | |||
FileSet sourceJar = new FileSet(); | |||
sourceJar.setProject(getProject()); | |||
sourceJar.setFile(jar); | |||
sourceJar.setDir(jar.getParentFile()); | |||
sources.add(sourceJar); | |||
@@ -313,6 +336,31 @@ public abstract class AbstractJarSignerTask extends Task { | |||
return sources; | |||
} | |||
/** | |||
* clone our path and add all explicitly specified FileSets as | |||
* well, patch in the jar attribute as a new fileset if it is | |||
* defined. | |||
* @return a path that contains all files to sign | |||
* @since Ant 1.7 | |||
*/ | |||
protected Path createUnifiedSourcePath() { | |||
Path p = path == null ? new Path(getProject()) : (Path) path.clone(); | |||
Vector s = createUnifiedSources(); | |||
Enumeration e = s.elements(); | |||
while (e.hasMoreElements()) { | |||
p.add((FileSet) e.nextElement()); | |||
} | |||
return p; | |||
} | |||
/** | |||
* Has either a path or a fileset been specified? | |||
* @since Ant 1.7 | |||
*/ | |||
protected boolean hasResources() { | |||
return path != null || filesets.size() > 0; | |||
} | |||
/** | |||
* add a value argument to a command | |||
* @param cmd command to manipulate | |||
@@ -19,13 +19,14 @@ package org.apache.tools.ant.taskdefs; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Vector; | |||
import java.util.Iterator; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.DirectoryScanner; | |||
import org.apache.tools.ant.Project; | |||
import org.apache.tools.ant.taskdefs.condition.IsSigned; | |||
import org.apache.tools.ant.types.FileSet; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.types.resources.FileResource; | |||
import org.apache.tools.ant.util.FileUtils; | |||
import org.apache.tools.ant.util.IdentityMapper; | |||
import org.apache.tools.ant.util.FileNameMapper; | |||
@@ -80,7 +81,7 @@ public class SignJar extends AbstractJarSignerTask { | |||
protected boolean lazy; | |||
/** | |||
* the output directory when using filesets. | |||
* the output directory when using paths. | |||
*/ | |||
protected File destDir; | |||
@@ -111,7 +112,7 @@ public class SignJar extends AbstractJarSignerTask { | |||
/** | |||
* error string for unit test verification {@value} | |||
*/ | |||
public static final String ERROR_SIGNEDJAR_AND_FILESETS = "You cannot specify the signed JAR when using filesets"; | |||
public static final String ERROR_SIGNEDJAR_AND_PATHS = "You cannot specify the signed JAR when using paths or filesets"; | |||
/** | |||
* error string for unit test verification: {@value} | |||
*/ | |||
@@ -252,13 +253,12 @@ public class SignJar extends AbstractJarSignerTask { | |||
*/ | |||
public void execute() throws BuildException { | |||
//validation logic | |||
final boolean hasFileset = filesets.size() > 0; | |||
final boolean hasJar = jar != null; | |||
final boolean hasSignedJar = signedjar != null; | |||
final boolean hasDestDir = destDir != null; | |||
final boolean hasMapper = mapper != null; | |||
if (!hasJar && !hasFileset) { | |||
if (!hasJar && !hasResources()) { | |||
throw new BuildException(ERROR_NO_SOURCE); | |||
} | |||
if (null == alias) { | |||
@@ -274,8 +274,8 @@ public class SignJar extends AbstractJarSignerTask { | |||
} | |||
if (hasFileset && hasSignedJar) { | |||
throw new BuildException(ERROR_SIGNEDJAR_AND_FILESETS); | |||
if (hasResources() && hasSignedJar) { | |||
throw new BuildException(ERROR_SIGNEDJAR_AND_PATHS); | |||
} | |||
//this isnt strictly needed, but by being fussy now, | |||
@@ -297,9 +297,9 @@ public class SignJar extends AbstractJarSignerTask { | |||
} | |||
//the rest of the method treats single jar like | |||
//a nested fileset with one file | |||
//a nested path with one file | |||
Vector sources = createUnifiedSources(); | |||
Path sources = createUnifiedSourcePath(); | |||
//set up our mapping policy | |||
FileNameMapper destMapper; | |||
if (hasMapper) { | |||
@@ -310,34 +310,26 @@ public class SignJar extends AbstractJarSignerTask { | |||
} | |||
//at this point the filesets are set up with lists of files, | |||
//at this point the paths are set up with lists of files, | |||
//and the mapper is ready to map from source dirs to dest files | |||
//now we iterate through every JAR giving source and dest names | |||
// deal with the filesets | |||
for (int i = 0; i < sources.size(); i++) { | |||
FileSet fs = (FileSet) sources.elementAt(i); | |||
//get all included files in a fileset | |||
DirectoryScanner ds = fs.getDirectoryScanner(getProject()); | |||
String[] jarFiles = ds.getIncludedFiles(); | |||
File baseDir = fs.getDir(getProject()); | |||
// deal with the paths | |||
Iterator iter = sources.iterator(); | |||
while (iter.hasNext()) { | |||
FileResource fr = (FileResource) iter.next(); | |||
//calculate our destination directory; it is either the destDir | |||
//attribute, or the base dir of the fileset (for in situ updates) | |||
File toDir = hasDestDir ? destDir : baseDir; | |||
//loop through all jars in the fileset | |||
for (int j = 0; j < jarFiles.length; j++) { | |||
String jarFile = jarFiles[j]; | |||
//determine the destination filename via the mapper | |||
String[] destFilenames = destMapper.mapFileName(jarFile); | |||
if (destFilenames == null || destFilenames.length != 1) { | |||
//we only like simple mappers. | |||
throw new BuildException(ERROR_BAD_MAP + jarFile); | |||
} | |||
File destFile = new File(toDir, destFilenames[0]); | |||
File jarSource = new File(baseDir, jarFile); | |||
signOneJar(jarSource, destFile); | |||
File toDir = hasDestDir ? destDir : fr.getBaseDir(); | |||
//determine the destination filename via the mapper | |||
String[] destFilenames = destMapper.mapFileName(fr.getName()); | |||
if (destFilenames == null || destFilenames.length != 1) { | |||
//we only like simple mappers. | |||
throw new BuildException(ERROR_BAD_MAP + fr.getFile()); | |||
} | |||
File destFile = new File(toDir, destFilenames[0]); | |||
signOneJar(fr.getFile(), destFile); | |||
} | |||
} finally { | |||
endExecution(); | |||
@@ -86,7 +86,21 @@ public class SignJarTest extends BuildFileTest { | |||
public void testFilesetAndSignedJar() { | |||
expectBuildExceptionContaining("testFilesetAndSignedJar", | |||
"incompatible attributes", | |||
SignJar.ERROR_SIGNEDJAR_AND_FILESETS); | |||
SignJar.ERROR_SIGNEDJAR_AND_PATHS); | |||
} | |||
public void testPath() { | |||
executeTarget("testPath"); | |||
} | |||
public void testPathAndJar() { | |||
executeTarget("testPathAndJar"); | |||
} | |||
public void testPathAndSignedJar() { | |||
expectBuildExceptionContaining("testPathAndSignedJar", | |||
"incompatible attributes", | |||
SignJar.ERROR_SIGNEDJAR_AND_PATHS); | |||
} | |||
public void testSignedJar() { | |||
@@ -100,7 +114,13 @@ public class SignJarTest extends BuildFileTest { | |||
public void testDestDirAndSignedJar() { | |||
expectBuildExceptionContaining("testFilesetAndSignedJar", | |||
"incompatible attributes", | |||
SignJar.ERROR_SIGNEDJAR_AND_FILESETS); | |||
SignJar.ERROR_SIGNEDJAR_AND_PATHS); | |||
} | |||
public void testDestDirAndSignedJar2() { | |||
expectBuildExceptionContaining("testPathAndSignedJar", | |||
"incompatible attributes", | |||
SignJar.ERROR_SIGNEDJAR_AND_PATHS); | |||
} | |||
public void testDestDirFileset() { | |||
@@ -111,6 +131,14 @@ public class SignJarTest extends BuildFileTest { | |||
executeTarget("testMapperFileset"); | |||
} | |||
public void testDestDirPath() { | |||
executeTarget("testDestDirPath"); | |||
} | |||
public void testMapperPath() { | |||
executeTarget("testMapperPath"); | |||
} | |||
public void testMapperNoDest() { | |||
expectBuildExceptionContaining("testMapperNoDest", | |||
"two mappers", | |||
@@ -180,4 +208,8 @@ public class SignJarTest extends BuildFileTest { | |||
executeTarget("testVerifyFileset"); | |||
} | |||
public void testVerifyPath() { | |||
executeTarget("testVerifyPath"); | |||
} | |||
} |