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> | <h3>Description</h3> | ||||
| <p>Signs JAR files with the <tt>jarsigner</tt> command line tool. | <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 | 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 | 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. | directory or explicit JAR file name is not provided, JARs are signed in place. | ||||
| </p> | </p> | ||||
| @@ -39,7 +39,7 @@ and <tt>lazy</tt> is false, the JAR is signed.</li> | |||||
| <tr> | <tr> | ||||
| <td valign="top">jar</td> | <td valign="top">jar</td> | ||||
| <td valign="top">the jar file to sign</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> | been used.</td> | ||||
| </tr> | </tr> | ||||
| <tr> | <tr> | ||||
| @@ -134,6 +134,11 @@ block</td> | |||||
| <td valign="top"><b>Description</b></td> | <td valign="top"><b>Description</b></td> | ||||
| <td align="center" valign="top"><b>Required</b></td> | <td align="center" valign="top"><b>Required</b></td> | ||||
| </tr> | </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> | <tr> | ||||
| <td valign="top">fileset</td> | <td valign="top">fileset</td> | ||||
| <td valign="top">fileset of JAR files to sign. </td> | <td valign="top">fileset of JAR files to sign. </td> | ||||
| @@ -167,7 +172,9 @@ alias="apache-group" storepass="secret"/> | |||||
| alias="testonly" keystore="testkeystore" | alias="testonly" keystore="testkeystore" | ||||
| storepass="apacheant" | storepass="apacheant" | ||||
| preservelastmodified="true"> | preservelastmodified="true"> | ||||
| <fileset dir="dist" includes="**/*.jar" /> | |||||
| <path> | |||||
| <fileset dir="dist" includes="**/*.jar" /> | |||||
| </path> | |||||
| <flattenmapper /> | <flattenmapper /> | ||||
| </signjar> | </signjar> | ||||
| </pre></blockquote> | </pre></blockquote> | ||||
| @@ -183,7 +190,9 @@ all be copied to this directory, not to subdirectories. | |||||
| storepass="apacheant" | storepass="apacheant" | ||||
| lazy="true" | lazy="true" | ||||
| > | > | ||||
| <fileset dir="dist" includes="**/*.jar" /> | |||||
| <path> | |||||
| <fileset dir="dist" includes="**/*.jar" /> | |||||
| </path> | |||||
| </signjar> | </signjar> | ||||
| </pre></blockquote> | </pre></blockquote> | ||||
| <p> | <p> | ||||
| @@ -118,6 +118,32 @@ | |||||
| </sign-base> | </sign-base> | ||||
| </target> | </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"> | <target name="testSignedJar" depends="jar"> | ||||
| <sign signedjar="${subdirtest.jar}"/> | <sign signedjar="${subdirtest.jar}"/> | ||||
| <assertSigned jar="${subdirtest.jar}"/> | <assertSigned jar="${subdirtest.jar}"/> | ||||
| @@ -139,6 +165,15 @@ | |||||
| <assertSigned jar="${subdirtest.jar}"/> | <assertSigned jar="${subdirtest.jar}"/> | ||||
| </target> | </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"> | <target name="testMapperNoDest" depends="jar"> | ||||
| <sign-base > | <sign-base > | ||||
| <flattenmapper /> | <flattenmapper /> | ||||
| @@ -154,6 +189,16 @@ | |||||
| <assertSigned jar="${subdirtest.jar}"/> | <assertSigned jar="${subdirtest.jar}"/> | ||||
| </target> | </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"> | <target name="testTwoMappers" depends="jar"> | ||||
| <sign-base destDir="${subdir}"> | <sign-base destDir="${subdir}"> | ||||
| <fileset file="${test.jar}" /> | <fileset file="${test.jar}" /> | ||||
| @@ -211,6 +256,14 @@ | |||||
| </verify-base> | </verify-base> | ||||
| </target> | </target> | ||||
| <target name="testVerifyPath" depends="basic"> | |||||
| <verify-base > | |||||
| <path> | |||||
| <pathelement location="${test.jar}" /> | |||||
| </path> | |||||
| </verify-base> | |||||
| </target> | |||||
| <target name="testVerifyNoArgs"> | <target name="testVerifyNoArgs"> | ||||
| <verify-base /> | <verify-base /> | ||||
| </target> | </target> | ||||
| @@ -21,6 +21,7 @@ import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
| import org.apache.tools.ant.types.FileSet; | 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.RedirectorElement; | ||||
| import org.apache.tools.ant.types.Environment; | 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 " | public static final String ERROR_NO_SOURCE = "jar must be set through jar attribute " | ||||
| + "or nested filesets"; | + "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 | * 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) { | public void addSysproperty(Environment.Variable sysp) { | ||||
| sysProperties.addVariable(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) | * 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, | //this lets us combine our logic for handling output directories, | ||||
| //mapping etc. | //mapping etc. | ||||
| FileSet sourceJar = new FileSet(); | FileSet sourceJar = new FileSet(); | ||||
| sourceJar.setProject(getProject()); | |||||
| sourceJar.setFile(jar); | sourceJar.setFile(jar); | ||||
| sourceJar.setDir(jar.getParentFile()); | sourceJar.setDir(jar.getParentFile()); | ||||
| sources.add(sourceJar); | sources.add(sourceJar); | ||||
| @@ -313,6 +336,31 @@ public abstract class AbstractJarSignerTask extends Task { | |||||
| return sources; | 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 | * add a value argument to a command | ||||
| * @param cmd command to manipulate | * @param cmd command to manipulate | ||||
| @@ -19,13 +19,14 @@ package org.apache.tools.ant.taskdefs; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.util.Vector; | |||||
| import java.util.Iterator; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.taskdefs.condition.IsSigned; | 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.FileUtils; | ||||
| import org.apache.tools.ant.util.IdentityMapper; | import org.apache.tools.ant.util.IdentityMapper; | ||||
| import org.apache.tools.ant.util.FileNameMapper; | import org.apache.tools.ant.util.FileNameMapper; | ||||
| @@ -80,7 +81,7 @@ public class SignJar extends AbstractJarSignerTask { | |||||
| protected boolean lazy; | protected boolean lazy; | ||||
| /** | /** | ||||
| * the output directory when using filesets. | |||||
| * the output directory when using paths. | |||||
| */ | */ | ||||
| protected File destDir; | protected File destDir; | ||||
| @@ -111,7 +112,7 @@ public class SignJar extends AbstractJarSignerTask { | |||||
| /** | /** | ||||
| * error string for unit test verification {@value} | * 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} | * error string for unit test verification: {@value} | ||||
| */ | */ | ||||
| @@ -252,13 +253,12 @@ public class SignJar extends AbstractJarSignerTask { | |||||
| */ | */ | ||||
| public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
| //validation logic | //validation logic | ||||
| final boolean hasFileset = filesets.size() > 0; | |||||
| final boolean hasJar = jar != null; | final boolean hasJar = jar != null; | ||||
| final boolean hasSignedJar = signedjar != null; | final boolean hasSignedJar = signedjar != null; | ||||
| final boolean hasDestDir = destDir != null; | final boolean hasDestDir = destDir != null; | ||||
| final boolean hasMapper = mapper != null; | final boolean hasMapper = mapper != null; | ||||
| if (!hasJar && !hasFileset) { | |||||
| if (!hasJar && !hasResources()) { | |||||
| throw new BuildException(ERROR_NO_SOURCE); | throw new BuildException(ERROR_NO_SOURCE); | ||||
| } | } | ||||
| if (null == alias) { | 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, | //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 | //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 | //set up our mapping policy | ||||
| FileNameMapper destMapper; | FileNameMapper destMapper; | ||||
| if (hasMapper) { | 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 | //and the mapper is ready to map from source dirs to dest files | ||||
| //now we iterate through every JAR giving source and dest names | //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 | //calculate our destination directory; it is either the destDir | ||||
| //attribute, or the base dir of the fileset (for in situ updates) | //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 { | } finally { | ||||
| endExecution(); | endExecution(); | ||||
| @@ -86,7 +86,21 @@ public class SignJarTest extends BuildFileTest { | |||||
| public void testFilesetAndSignedJar() { | public void testFilesetAndSignedJar() { | ||||
| expectBuildExceptionContaining("testFilesetAndSignedJar", | expectBuildExceptionContaining("testFilesetAndSignedJar", | ||||
| "incompatible attributes", | "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() { | public void testSignedJar() { | ||||
| @@ -100,7 +114,13 @@ public class SignJarTest extends BuildFileTest { | |||||
| public void testDestDirAndSignedJar() { | public void testDestDirAndSignedJar() { | ||||
| expectBuildExceptionContaining("testFilesetAndSignedJar", | expectBuildExceptionContaining("testFilesetAndSignedJar", | ||||
| "incompatible attributes", | "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() { | public void testDestDirFileset() { | ||||
| @@ -111,6 +131,14 @@ public class SignJarTest extends BuildFileTest { | |||||
| executeTarget("testMapperFileset"); | executeTarget("testMapperFileset"); | ||||
| } | } | ||||
| public void testDestDirPath() { | |||||
| executeTarget("testDestDirPath"); | |||||
| } | |||||
| public void testMapperPath() { | |||||
| executeTarget("testMapperPath"); | |||||
| } | |||||
| public void testMapperNoDest() { | public void testMapperNoDest() { | ||||
| expectBuildExceptionContaining("testMapperNoDest", | expectBuildExceptionContaining("testMapperNoDest", | ||||
| "two mappers", | "two mappers", | ||||
| @@ -180,4 +208,8 @@ public class SignJarTest extends BuildFileTest { | |||||
| executeTarget("testVerifyFileset"); | executeTarget("testVerifyFileset"); | ||||
| } | } | ||||
| public void testVerifyPath() { | |||||
| executeTarget("testVerifyPath"); | |||||
| } | |||||
| } | } | ||||