diff --git a/src/main/org/apache/tools/ant/taskdefs/Echo.java b/src/main/org/apache/tools/ant/taskdefs/Echo.java index f6be4808d..02bd1f0d3 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Echo.java +++ b/src/main/org/apache/tools/ant/taskdefs/Echo.java @@ -67,6 +67,8 @@ import java.io.IOException; * * @author costin@dnt.ro * + * @since Ant 1.1 + * * @ant.task category="utility" */ public class Echo extends Task { diff --git a/src/main/org/apache/tools/ant/taskdefs/Jar.java b/src/main/org/apache/tools/ant/taskdefs/Jar.java index e964e172e..946d920fc 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Jar.java +++ b/src/main/org/apache/tools/ant/taskdefs/Jar.java @@ -59,6 +59,7 @@ import org.apache.tools.ant.FileScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.ZipFileSet; import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.util.StringUtils; import org.apache.tools.zip.ZipOutputStream; import java.io.IOException; @@ -80,6 +81,8 @@ import java.util.Enumeration; * @author James Davidson duncan@x180.com * @author Brian Deitte bdeitte@macromedia.com * + * @since 1.1 + * * @ant.task category="packaging" */ public class Jar extends Zip { @@ -88,6 +91,8 @@ public class Jar extends Zip { /** merged manifests added through addConfiguredManifest */ private Manifest configuredManifest; + /** shadow of the above if upToDate check alters the value */ + private Manifest savedConfiguredManifest; /** merged manifests added through filesets */ private Manifest filesetManifest; @@ -108,9 +113,10 @@ public class Jar extends Zip { private Manifest manifest; /** - * The file found from the 'manifest' attribute. This can be either the location of a manifest, - * or the name of a jar added through a fileset. If its the name of an added jar, the manifest is - * looked for in META-INF/MANIFEST.MF + * The file found from the 'manifest' attribute. This can be + * either the location of a manifest, or the name of a jar added + * through a fileset. If its the name of an added jar, the + * manifest is looked for in META-INF/MANIFEST.MF */ private File manifestFile; @@ -145,19 +151,20 @@ public class Jar extends Zip { index = flag; } - public void addConfiguredManifest(Manifest newManifest) throws ManifestException { + public void addConfiguredManifest(Manifest newManifest) + throws ManifestException { if (configuredManifest == null) { configuredManifest = newManifest; - } - else { + } else { configuredManifest.merge(newManifest); } + savedConfiguredManifest = configuredManifest; } public void setManifest(File manifestFile) { if (!manifestFile.exists()) { - throw new BuildException("Manifest file: " + manifestFile + " does not exist.", - getLocation()); + throw new BuildException("Manifest file: " + manifestFile + + " does not exist.", getLocation()); } this.manifestFile = manifestFile; @@ -172,9 +179,10 @@ public class Jar extends Zip { newManifest = getManifest(r); } catch (IOException e) { - throw new BuildException("Unable to read manifest file: " + manifestFile, e); - } - finally { + throw new BuildException("Unable to read manifest file: " + + manifestFile + + " (" + e.getMessage() + ")", e); + } finally { if (r != null) { try { r.close(); @@ -195,10 +203,12 @@ public class Jar extends Zip { } catch (ManifestException e) { log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR); - throw new BuildException("Invalid Manifest: " + manifestFile, e, getLocation()); + throw new BuildException("Invalid Manifest: " + manifestFile, + e, getLocation()); } catch (IOException e) { - throw new BuildException("Unable to read manifest file", e); + throw new BuildException("Unable to read manifest file" + + " (" + e.getMessage() + ")", e); } return newManifest; } @@ -219,13 +229,14 @@ public class Jar extends Zip { throws IOException, BuildException { String ls = System.getProperty("line.separator"); + try { Manifest finalManifest = Manifest.getDefaultManifest(); if (manifest == null) { if (manifestFile != null) { - // if we haven't got the manifest yet, attempt to get it now and - // have manifest be the final merge + // if we haven't got the manifest yet, attempt to + // get it now and have manifest be the final merge manifest = getManifest(manifestFile); finalManifest.merge(filesetManifest); finalManifest.merge(configuredManifest); @@ -234,7 +245,8 @@ public class Jar extends Zip { else if (configuredManifest != null) { // configuredManifest is the final merge finalManifest.merge(filesetManifest); - finalManifest.merge(configuredManifest, ! mergeManifestsMain); + finalManifest.merge(configuredManifest, + ! mergeManifestsMain); } else if (filesetManifest != null) { // filesetManifest is the final (and only) merge @@ -247,11 +259,14 @@ public class Jar extends Zip { finalManifest.merge(manifest, ! mergeManifestsMain); } - for (Enumeration e = finalManifest.getWarnings(); e.hasMoreElements(); ) { - log("Manifest warning: " + (String)e.nextElement(), Project.MSG_WARN); + for (Enumeration e = finalManifest.getWarnings(); + e.hasMoreElements(); ) { + log("Manifest warning: " + (String)e.nextElement(), + Project.MSG_WARN); } - // need to set the line.separator as \r\n due to a bug with the jar verifier + // need to set the line.separator as \r\n due to a bug + // with the jar verifier System.getProperties().put("line.separator", "\r\n"); zipDir(null, zOut, "META-INF/"); @@ -261,8 +276,10 @@ public class Jar extends Zip { finalManifest.write(writer); writer.flush(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); - super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", System.currentTimeMillis(), null); + ByteArrayInputStream bais = + new ByteArrayInputStream(baos.toByteArray()); + super.zipFile(bais, zOut, "META-INF/MANIFEST.MF", + System.currentTimeMillis(), null); super.initZipOutputStream(zOut); } catch (ManifestException e) { @@ -294,7 +311,8 @@ public class Jar extends Zip { private void createIndexList(ZipOutputStream zOut) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // encoding must be UTF8 as specified in the specs. - PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, "UTF8")); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos, + "UTF8")); // version-info blankline writer.println("JarIndex-Version: 1.0"); @@ -329,7 +347,8 @@ public class Jar extends Zip { } writer.flush(); - ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ByteArrayInputStream bais = + new ByteArrayInputStream(baos.toByteArray()); super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(), null); } @@ -349,7 +368,8 @@ public class Jar extends Zip { /** * Overriden from Zip class to deal with manifests */ - protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, long lastModified, File file) + protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath, + long lastModified, File file) throws IOException { if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { @@ -361,7 +381,8 @@ public class Jar extends Zip { private void filesetManifest(File file, InputStream is) { if (manifestFile != null && manifestFile.equals(file)) { - // If this is the same name specified in 'manifest', this is the manifest to use + // If this is the same name specified in 'manifest', this + // is the manifest to use log("Found manifest " + file, Project.MSG_VERBOSE); if (is != null) { manifest = getManifest(new InputStreamReader(is)); @@ -372,7 +393,8 @@ public class Jar extends Zip { } else if (mergeManifests) { // we add this to our group of fileset manifests - log("Found manifest to merge in file " + file, Project.MSG_VERBOSE); + log("Found manifest to merge in file " + file, + Project.MSG_VERBOSE); try { @@ -390,8 +412,10 @@ public class Jar extends Zip { } else { // assuming 'skip' otherwise - log("File " + file + " includes a META-INF/MANIFEST.MF which will be ignored. " + - "To include this file, set filesetManifest to a value other than 'skip'.", Project.MSG_WARN); + log("File " + file + + " includes a META-INF/MANIFEST.MF which will be ignored. " + + "To include this file, set filesetManifest to a value other " + + "than 'skip'.", Project.MSG_WARN); } } @@ -399,27 +423,33 @@ public class Jar extends Zip { * Check whether the archive is up-to-date; * @param scanners list of prepared scanners containing files to archive * @param zipFile intended archive file (may or may not exist) - * @return true if nothing need be done (may have done something already); false if - * archive creation should proceed + * @return true if nothing need be done (may have done something + * already); false if archive creation should proceed * @exception BuildException if it likes */ - protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException { + protected boolean isUpToDate(FileScanner[] scanners, File zipFile) + throws BuildException { // need to handle manifest as a special check if (configuredManifest != null || manifestFile == null) { java.util.zip.ZipFile theZipFile = null; try { theZipFile = new java.util.zip.ZipFile(zipFile); - java.util.zip.ZipEntry entry = theZipFile.getEntry("META-INF/MANIFEST.MF"); + java.util.zip.ZipEntry entry = + theZipFile.getEntry("META-INF/MANIFEST.MF"); if (entry == null) { - log("Updating jar since the current jar has no manifest", Project.MSG_VERBOSE); + log("Updating jar since the current jar has no manifest", + Project.MSG_VERBOSE); return false; } - Manifest currentManifest = new Manifest(new InputStreamReader(theZipFile.getInputStream(entry))); + Manifest currentManifest = + new Manifest(new InputStreamReader(theZipFile + .getInputStream(entry))); if (configuredManifest == null) { - configuredManifest = Manifest.getDefaultManifest(); + configuredManifest = Manifest.getDefaultManifest(); } if (!currentManifest.equals(configuredManifest)) { - log("Updating jar since jar manifest has changed", Project.MSG_VERBOSE); + log("Updating jar since jar manifest has changed", + Project.MSG_VERBOSE); return false; } } @@ -462,6 +492,8 @@ public class Jar extends Zip { super.cleanUp(); manifest = null; + configuredManifest = savedConfiguredManifest; + filesetManifest = null; } /** @@ -474,7 +506,6 @@ public class Jar extends Zip { public void reset() { super.reset(); configuredManifest = null; - filesetManifest = null; mergeManifests = false; mergeManifestsMain = false; manifestFile = null; diff --git a/src/main/org/apache/tools/ant/taskdefs/Zip.java b/src/main/org/apache/tools/ant/taskdefs/Zip.java index 96b38ed66..3b4770c15 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Zip.java +++ b/src/main/org/apache/tools/ant/taskdefs/Zip.java @@ -61,6 +61,7 @@ import java.io.FileInputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; +import java.util.Enumeration; import java.util.Hashtable; import java.util.Stack; import java.util.Vector; @@ -73,6 +74,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.types.PatternSet; import org.apache.tools.ant.types.ZipFileSet; import org.apache.tools.ant.types.ZipScanner; import org.apache.tools.ant.util.FileUtils; @@ -88,6 +90,8 @@ import org.apache.tools.zip.ZipEntry; * @author Jon S. Stevens jon@clearink.com * @author Stefan Bodewig * + * @since Ant 1.1 + * * @ant.task category="packaging" */ public class Zip extends MatchingTask { @@ -96,9 +100,12 @@ public class Zip extends MatchingTask { private File baseDir; protected Hashtable entries = new Hashtable(); private Vector groupfilesets = new Vector(); + private Vector filesetsFromGroupfilesets = new Vector(); protected String duplicate = "add"; private boolean doCompress = true; private boolean doUpdate = false; + // shadow of the above if the value is altered in execute + private boolean savedDoUpdate = false; private boolean doFilesonly = false; protected String archiveType = "zip"; @@ -109,9 +116,11 @@ public class Zip extends MatchingTask { protected Hashtable addedDirs = new Hashtable(); private Vector addedFiles = new Vector(); - /** true when we are adding new files into the Zip file, as opposed to - adding back the unchanged files */ - private boolean addingNewFiles; + /** + * true when we are adding new files into the Zip file, as opposed + * to adding back the unchanged files + */ + private boolean addingNewFiles = false; /** * Encoding to use for filenames, defaults to the platform's @@ -178,6 +187,7 @@ public class Zip extends MatchingTask { */ public void setUpdate(boolean c) { doUpdate = c; + savedDoUpdate = c; } /** @@ -254,13 +264,15 @@ public class Zip extends MatchingTask { public void execute() throws BuildException { if (baseDir == null && filesets.size() == 0 - && groupfilesets.size() == 0 && "zip".equals(archiveType)) { - throw new BuildException( "basedir attribute must be set, or at least " + - "one fileset must be given!" ); + && groupfilesets.size() == 0 && "zip".equals(archiveType)) { + throw new BuildException( "basedir attribute must be set, " + + "or at least " + + "one fileset must be given!" ); } if (zipFile == null) { - throw new BuildException("You must specify the " + archiveType + " file to create!"); + throw new BuildException("You must specify the " + + archiveType + " file to create!"); } // Renamed version of original file, if it exists @@ -273,18 +285,21 @@ public class Zip extends MatchingTask { if (doUpdate) { FileUtils fileUtils = FileUtils.newFileUtils(); - renamedFile = fileUtils.createTempFile("zip", ".tmp", - fileUtils.getParentFile(zipFile)); + renamedFile = + fileUtils.createTempFile("zip", ".tmp", + fileUtils.getParentFile(zipFile)); try { if (!zipFile.renameTo(renamedFile)) { - throw new BuildException("Unable to rename old file to temporary file"); + throw new BuildException("Unable to rename old file to " + + "temporary file"); } } catch (SecurityException e) { - throw new BuildException("Not allowed to rename old file to temporary file"); + throw new BuildException("Not allowed to rename old file to " + + "temporary file"); } } @@ -298,15 +313,17 @@ public class Zip extends MatchingTask { File basedir = scanner.getBasedir(); for (int j=0; jEnsure parent directories have been added as well. */ protected void addFiles(FileScanner scanner, ZipOutputStream zOut, - String prefix, String fullpath) throws IOException { + String prefix, String fullpath) + throws IOException { + if (prefix.length() > 0 && fullpath.length() > 0) { - throw new BuildException("Both prefix and fullpath attributes may not be set on the same fileset."); + throw new BuildException("Both prefix and fullpath attributes must" + + " not be set on the same fileset."); } File thisBaseDir = scanner.getBasedir(); @@ -439,7 +461,9 @@ public class Zip extends MatchingTask { // directories that matched include patterns String[] dirs = scanner.getIncludedDirectories(); if (dirs.length > 0 && fullpath.length() > 0) { - throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file."); + throw new BuildException("fullpath attribute may only be specified" + + " for filesets that specify a single" + + " file."); } for (int i = 0; i < dirs.length; i++) { if ("".equals(dirs[i])) { @@ -455,7 +479,9 @@ public class Zip extends MatchingTask { // files that matched include patterns String[] files = scanner.getIncludedFiles(); if (files.length > 1 && fullpath.length() > 0) { - throw new BuildException("fullpath attribute may only be specified for filesets that specify a single file."); + throw new BuildException("fullpath attribute may only be specified" + + " for filesets that specify a single" + + "file."); } for (int i = 0; i < files.length; i++) { File f = new File(thisBaseDir, files[i]); @@ -476,13 +502,15 @@ public class Zip extends MatchingTask { } protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds, - ZipOutputStream zOut, String prefix, String fullpath) + ZipOutputStream zOut, String prefix, + String fullpath) throws IOException { log("adding zip entries: " + fullpath, Project.MSG_VERBOSE); if (prefix.length() > 0 && fullpath.length() > 0) { - throw new BuildException("Both prefix and fullpath attributes may not be set on the same fileset."); + throw new BuildException("Both prefix and fullpath attributes must" + + " not be set on the same fileset."); } ZipScanner zipScanner = (ZipScanner) ds; @@ -504,7 +532,8 @@ public class Zip extends MatchingTask { } else { addParentDirs(null, vPath, zOut, prefix); if (! entry.isDirectory()) { - zipFile(in, zOut, prefix+vPath, entry.getTime(), zipSrc); + zipFile(in, zOut, prefix+vPath, entry.getTime(), + zipSrc); } } } @@ -535,37 +564,46 @@ public class Zip extends MatchingTask { // In this case using java.util.zip will not work // because it does not permit a zero-entry archive. // Must create it manually. - log("Note: creating empty "+archiveType+" archive " + zipFile, Project.MSG_INFO); + log("Note: creating empty "+archiveType+" archive " + zipFile, + Project.MSG_INFO); + OutputStream os = null; try { - OutputStream os = new FileOutputStream(zipFile); - try { - // Cf. PKZIP specification. - byte[] empty = new byte[22]; - empty[0] = 80; // P - empty[1] = 75; // K - empty[2] = 5; - empty[3] = 6; - // remainder zeros - os.write(empty); - } finally { - os.close(); - } + os = new FileOutputStream(zipFile); + // Cf. PKZIP specification. + byte[] empty = new byte[22]; + empty[0] = 80; // P + empty[1] = 75; // K + empty[2] = 5; + empty[3] = 6; + // remainder zeros + os.write(empty); } catch (IOException ioe) { - throw new BuildException("Could not create empty ZIP archive", ioe, location); + throw new BuildException("Could not create empty ZIP archive " + + "(" + ioe.getMessage() + ")", ioe, + location); + } finally { + if (os != null) { + try { + os.close(); + } catch (IOException e) { + } + } } return true; } /** - * Check whether the archive is up-to-date; and handle behavior for empty archives. + * Check whether the archive is up-to-date; and handle behavior + * for empty archives. * @param scanners list of prepared scanners containing files to archive * @param zipFile intended archive file (may or may not exist) - * @return true if nothing need be done (may have done something already); false if - * archive creation should proceed + * @return true if nothing need be done (may have done something + * already); false if archive creation should proceed * @exception BuildException if it likes */ - protected boolean isUpToDate(FileScanner[] scanners, File zipFile) throws BuildException + protected boolean isUpToDate(FileScanner[] scanners, File zipFile) + throws BuildException { String[][] fileNames = grabFileNames(scanners); File[] files = grabFiles(scanners, fileNames); @@ -575,7 +613,8 @@ public class Zip extends MatchingTask { " because no files were included.", Project.MSG_WARN); return true; } else if (emptyBehavior.equals("fail")) { - throw new BuildException("Cannot create "+archiveType+" archive " + zipFile + + throw new BuildException("Cannot create "+archiveType + +" archive " + zipFile + ": no files were included.", location); } else { // Create. @@ -584,12 +623,13 @@ public class Zip extends MatchingTask { } else { for (int i = 0; i < files.length; ++i) { if (files[i].equals(zipFile)) { - throw new BuildException("A zip file cannot include itself", location); + throw new BuildException("A zip file cannot include itself", + location); } } if (!zipFile.exists()) { - return false; + return false; } SourceFileScanner sfs = new SourceFileScanner(this); @@ -677,12 +717,15 @@ public class Zip extends MatchingTask { } else if (duplicate.equals("fail")) { - throw new BuildException("Duplicate file " + vPath + " was found and the duplicate attribute is 'fail'."); + throw new BuildException("Duplicate file " + vPath + + " was found and the duplicate " + + "attribute is 'fail'."); } else { // duplicate equal to add, so we continue - log("duplicate file " + vPath + " found, adding.", Project.MSG_VERBOSE); + log("duplicate file " + vPath + + " found, adding.", Project.MSG_VERBOSE); } } else @@ -754,7 +797,8 @@ public class Zip extends MatchingTask { throws IOException { if (file.equals(zipFile)) { - throw new BuildException("A zip file cannot include itself", location); + throw new BuildException("A zip file cannot include itself", + location); } FileInputStream fIn = new FileInputStream(file); @@ -859,6 +903,14 @@ public class Zip extends MatchingTask { addedDirs.clear(); addedFiles.removeAllElements(); entries.clear(); + addingNewFiles = false; + doUpdate = savedDoUpdate; + Enumeration enum = filesetsFromGroupfilesets.elements(); + while (enum.hasMoreElements()) { + ZipFileSet zf = (ZipFileSet) enum.nextElement(); + filesets.removeElement(zf); + } + filesetsFromGroupfilesets.removeAllElements(); } /** @@ -880,7 +932,6 @@ public class Zip extends MatchingTask { emptyBehavior = "skip"; doUpdate = false; doFilesonly = false; - addingNewFiles = false; encoding = null; }