PR: 13296 Submitted by: bdeitte@macromedia.com (Brian Deitte) git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@273570 13f79535-47bb-0310-9956-ffa450edef68master
@@ -61,6 +61,8 @@ Fixed bugs: | |||||
Other changes: | Other changes: | ||||
-------------- | -------------- | ||||
* The filesetmanifest attribute of <jar> has been reenabled. | |||||
* The start and end tokens for <translate> may now be longer than a | * The start and end tokens for <translate> may now be longer than a | ||||
single character. | single character. | ||||
@@ -119,6 +119,12 @@ being wrapped and continued on the next line. | |||||
<td valign="top">the manifest file to use. 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 task expects the manifest to be in the jar at META-INF/MANIFEST.MF</td> | <td valign="top">the manifest file to use. 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 task expects the manifest to be in the jar at META-INF/MANIFEST.MF</td> | ||||
<td valign="top" align="center">No</td> | <td valign="top" align="center">No</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">filesetmanifest</td> | |||||
<td valign="top">behavior when a Manifest is found in a zipfileset or zipgroupfileset file is found. Valid values are "skip", "merge", and "mergewithoutmain". "merge" will merge all of the manifests together, and merge this into any other specified manifests. "mergewithoutmain" merges everything but the Main section of the manifests. Default value is "skip". | |||||
</td> | |||||
<td valign="top" align="center">No</td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td valign="top">update</td> | <td valign="top">update</td> | ||||
<td valign="top">indicates whether to update or overwrite | <td valign="top">indicates whether to update or overwrite | ||||
@@ -102,11 +102,6 @@ public class Jar extends Zip { | |||||
*/ | */ | ||||
private FilesetManifestConfig filesetManifestConfig; | private FilesetManifestConfig filesetManifestConfig; | ||||
/** | |||||
* Whether to create manifest file on finalizeOutputStream? | |||||
*/ | |||||
private boolean manifestOnFinalize = true; | |||||
/** | /** | ||||
* whether to merge the main section of fileset manifests; | * whether to merge the main section of fileset manifests; | ||||
* value is true if filesetmanifest is 'merge' | * value is true if filesetmanifest is 'merge' | ||||
@@ -243,12 +238,16 @@ public class Jar extends Zip { | |||||
* | * | ||||
* @param config setting for found manifest behavior. | * @param config setting for found manifest behavior. | ||||
*/ | */ | ||||
/* | |||||
public void setFilesetmanifest(FilesetManifestConfig config) { | public void setFilesetmanifest(FilesetManifestConfig config) { | ||||
filesetManifestConfig = config; | filesetManifestConfig = config; | ||||
mergeManifestsMain = "merge".equals(config.getValue()); | mergeManifestsMain = "merge".equals(config.getValue()); | ||||
if (filesetManifestConfig != null | |||||
&& ! filesetManifestConfig.getValue().equals("skip")) { | |||||
doubleFilePass = true; | |||||
} | |||||
} | } | ||||
*/ | |||||
/** | /** | ||||
* Adds a zipfileset to include in the META-INF directory. | * Adds a zipfileset to include in the META-INF directory. | ||||
@@ -263,16 +262,15 @@ public class Jar extends Zip { | |||||
protected void initZipOutputStream(ZipOutputStream zOut) | protected void initZipOutputStream(ZipOutputStream zOut) | ||||
throws IOException, BuildException { | throws IOException, BuildException { | ||||
if (filesetManifestConfig == null | |||||
|| filesetManifestConfig.getValue().equals("skip")) { | |||||
manifestOnFinalize = false; | |||||
if (! skipWriting) { | |||||
Manifest jarManifest = createManifest(); | Manifest jarManifest = createManifest(); | ||||
writeManifest(zOut, jarManifest); | writeManifest(zOut, jarManifest); | ||||
} | } | ||||
} | } | ||||
private Manifest createManifest() | private Manifest createManifest() | ||||
throws IOException, BuildException { | |||||
throws BuildException { | |||||
try { | try { | ||||
Manifest finalManifest = Manifest.getDefaultManifest(); | Manifest finalManifest = Manifest.getDefaultManifest(); | ||||
@@ -332,10 +330,6 @@ public class Jar extends Zip { | |||||
protected void finalizeZipOutputStream(ZipOutputStream zOut) | protected void finalizeZipOutputStream(ZipOutputStream zOut) | ||||
throws IOException, BuildException { | throws IOException, BuildException { | ||||
if (manifestOnFinalize) { | |||||
Manifest jarManifest = createManifest(); | |||||
writeManifest(zOut, jarManifest); | |||||
} | |||||
if (index) { | if (index) { | ||||
createIndexList(zOut); | createIndexList(zOut); | ||||
@@ -402,7 +396,9 @@ public class Jar extends Zip { | |||||
protected void zipFile(File file, ZipOutputStream zOut, String vPath) | protected void zipFile(File file, ZipOutputStream zOut, String vPath) | ||||
throws IOException { | throws IOException { | ||||
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | ||||
filesetManifest(file, null); | |||||
if (! doubleFilePass || (doubleFilePass && skipWriting)) { | |||||
filesetManifest(file, null); | |||||
} | |||||
} else { | } else { | ||||
super.zipFile(file, zOut, vPath); | super.zipFile(file, zOut, vPath); | ||||
} | } | ||||
@@ -415,7 +411,9 @@ public class Jar extends Zip { | |||||
long lastModified, File file) | long lastModified, File file) | ||||
throws IOException { | throws IOException { | ||||
if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | if ("META-INF/MANIFEST.MF".equalsIgnoreCase(vPath)) { | ||||
filesetManifest(file, is); | |||||
if (! doubleFilePass || (doubleFilePass && skipWriting)) { | |||||
filesetManifest(file, is); | |||||
} | |||||
} else { | } else { | ||||
super.zipFile(is, zOut, vPath, lastModified, null); | super.zipFile(is, zOut, vPath, lastModified, null); | ||||
} | } | ||||
@@ -539,9 +537,13 @@ public class Jar extends Zip { | |||||
protected void cleanUp() { | protected void cleanUp() { | ||||
super.cleanUp(); | super.cleanUp(); | ||||
manifest = null; | |||||
configuredManifest = savedConfiguredManifest; | |||||
filesetManifest = null; | |||||
// we want to save this info if we are going to make another pass | |||||
if (! doubleFilePass || (doubleFilePass && ! skipWriting)) | |||||
{ | |||||
manifest = null; | |||||
configuredManifest = savedConfiguredManifest; | |||||
filesetManifest = null; | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -115,6 +115,10 @@ public class Zip extends MatchingTask { | |||||
protected Hashtable addedDirs = new Hashtable(); | protected Hashtable addedDirs = new Hashtable(); | ||||
private Vector addedFiles = new Vector(); | private Vector addedFiles = new Vector(); | ||||
protected boolean doubleFilePass = false; | |||||
protected boolean skipWriting = false; | |||||
/** | /** | ||||
* true when we are adding new files into the Zip file, as opposed | * true when we are adding new files into the Zip file, as opposed | ||||
* to adding back the unchanged files | * to adding back the unchanged files | ||||
@@ -272,6 +276,20 @@ public class Zip extends MatchingTask { | |||||
* validate and build | * validate and build | ||||
*/ | */ | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
if (doubleFilePass) { | |||||
skipWriting = true; | |||||
executeMain(); | |||||
skipWriting = false; | |||||
executeMain(); | |||||
} | |||||
else { | |||||
executeMain(); | |||||
} | |||||
} | |||||
public void executeMain() throws BuildException { | |||||
if (baseDir == null && filesets.size() == 0 | if (baseDir == null && filesets.size() == 0 | ||||
&& groupfilesets.size() == 0 && "zip".equals(archiveType)) { | && groupfilesets.size() == 0 && "zip".equals(archiveType)) { | ||||
throw new BuildException("basedir attribute must be set, " | throw new BuildException("basedir attribute must be set, " | ||||
@@ -690,21 +708,23 @@ public class Zip extends MatchingTask { | |||||
log("adding directory " + vPath, Project.MSG_VERBOSE); | log("adding directory " + vPath, Project.MSG_VERBOSE); | ||||
addedDirs.put(vPath, vPath); | addedDirs.put(vPath, vPath); | ||||
ZipEntry ze = new ZipEntry (vPath); | |||||
if (dir != null && dir.exists()) { | |||||
ze.setTime(dir.lastModified()); | |||||
} else { | |||||
ze.setTime(System.currentTimeMillis()); | |||||
} | |||||
ze.setSize (0); | |||||
ze.setMethod (ZipEntry.STORED); | |||||
// This is faintly ridiculous: | |||||
ze.setCrc (EMPTY_CRC); | |||||
if (! skipWriting) { | |||||
ZipEntry ze = new ZipEntry (vPath); | |||||
if (dir != null && dir.exists()) { | |||||
ze.setTime(dir.lastModified()); | |||||
} else { | |||||
ze.setTime(System.currentTimeMillis()); | |||||
} | |||||
ze.setSize (0); | |||||
ze.setMethod (ZipEntry.STORED); | |||||
// This is faintly ridiculous: | |||||
ze.setCrc (EMPTY_CRC); | |||||
// this is 040775 | MS-DOS directory flag in reverse byte order | |||||
ze.setExternalAttributes(0x41FD0010L); | |||||
// this is 040775 | MS-DOS directory flag in reverse byte order | |||||
ze.setExternalAttributes(0x41FD0010L); | |||||
zOut.putNextEntry (ze); | |||||
zOut.putNextEntry (ze); | |||||
} | |||||
} | } | ||||
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath, | ||||
@@ -730,61 +750,63 @@ public class Zip extends MatchingTask { | |||||
entries.put(vPath, vPath); | entries.put(vPath, vPath); | ||||
ZipEntry ze = new ZipEntry(vPath); | |||||
ze.setTime(lastModified); | |||||
/* | |||||
* XXX ZipOutputStream.putEntry expects the ZipEntry to know its | |||||
* size and the CRC sum before you start writing the data when using | |||||
* STORED mode. | |||||
* | |||||
* This forces us to process the data twice. | |||||
* | |||||
* I couldn't find any documentation on this, just found out by try | |||||
* and error. | |||||
*/ | |||||
if (!doCompress) { | |||||
long size = 0; | |||||
CRC32 cal = new CRC32(); | |||||
if (!in.markSupported()) { | |||||
// Store data into a byte[] | |||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
size += count; | |||||
cal.update(buffer, 0, count); | |||||
bos.write(buffer, 0, count); | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
in = new ByteArrayInputStream(bos.toByteArray()); | |||||
if (! skipWriting) { | |||||
ZipEntry ze = new ZipEntry(vPath); | |||||
ze.setTime(lastModified); | |||||
/* | |||||
* XXX ZipOutputStream.putEntry expects the ZipEntry to know its | |||||
* size and the CRC sum before you start writing the data when using | |||||
* STORED mode. | |||||
* | |||||
* This forces us to process the data twice. | |||||
* | |||||
* I couldn't find any documentation on this, just found out by try | |||||
* and error. | |||||
*/ | |||||
if (!doCompress) { | |||||
long size = 0; | |||||
CRC32 cal = new CRC32(); | |||||
if (!in.markSupported()) { | |||||
// Store data into a byte[] | |||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
size += count; | |||||
cal.update(buffer, 0, count); | |||||
bos.write(buffer, 0, count); | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
in = new ByteArrayInputStream(bos.toByteArray()); | |||||
} else { | |||||
in.mark(Integer.MAX_VALUE); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
size += count; | |||||
cal.update(buffer, 0, count); | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
in.reset(); | |||||
} else { | |||||
in.mark(Integer.MAX_VALUE); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
size += count; | |||||
cal.update(buffer, 0, count); | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
in.reset(); | |||||
} | |||||
ze.setSize(size); | |||||
ze.setCrc(cal.getValue()); | |||||
} | } | ||||
ze.setSize(size); | |||||
ze.setCrc(cal.getValue()); | |||||
} | |||||
zOut.putNextEntry(ze); | |||||
zOut.putNextEntry(ze); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
if (count != 0) { | |||||
zOut.write(buffer, 0, count); | |||||
} | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
byte[] buffer = new byte[8 * 1024]; | |||||
int count = 0; | |||||
do { | |||||
if (count != 0) { | |||||
zOut.write(buffer, 0, count); | |||||
} | |||||
count = in.read(buffer, 0, buffer.length); | |||||
} while (count != -1); | |||||
} | |||||
addedFiles.addElement(vPath); | addedFiles.addElement(vPath); | ||||
} | } | ||||