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"); | |||
| } | |||
| } | |||