@@ -344,7 +344,11 @@ public class Zip extends MatchingTask {
// we don't need to update if the original file doesn't exist
// we don't need to update if the original file doesn't exist
addingNewFiles = true;
addingNewFiles = true;
doUpdate = doUpdate && zipFile.exists();
if (doUpdate && !zipFile.exists()) {
doUpdate = false;
log("ignoring update attribute as " + archiveType
+ " doesn't exist.", Project.MSG_DEBUG);
}
// Add the files found in groupfileset to fileset
// Add the files found in groupfileset to fileset
for (int i = 0; i < groupfilesets.size(); i++) {
for (int i = 0; i < groupfilesets.size(); i++) {
@@ -381,14 +385,16 @@ public class Zip extends MatchingTask {
vfss.copyInto(fss);
vfss.copyInto(fss);
boolean success = false;
boolean success = false;
try {
try {
Resource[][] addThem = getResourcesToAdd(fss, zipFile, false);
// can also handle empty archives
ArchiveState state = getResourcesToAdd(fss, zipFile, false);
// quick exit if the target is up to date
// quick exit if the target is up to date
// can also handle empty archives
if (isEmpty(addThem)) {
if (!state.isOutOfDate()) {
return;
return;
}
}
Resource[][] addThem = state.getResourcesToAdd();
if (doUpdate) {
if (doUpdate) {
renamedFile =
renamedFile =
fileUtils.createTempFile("zip", ".tmp",
fileUtils.createTempFile("zip", ".tmp",
@@ -687,17 +693,38 @@ public class Zip extends MatchingTask {
* out-of-date. Subclasses overriding this method are supposed to
* out-of-date. Subclasses overriding this method are supposed to
* set this value correctly in their call to
* set this value correctly in their call to
* super.getResourcesToAdd.
* super.getResourcesToAdd.
* @return an array of resources to add for each fileset passed in.
* @return an array of resources to add for each fileset passed in as well
* as a flag that indicates whether the archive is uptodate.
*
*
* @exception BuildException if it likes
* @exception BuildException if it likes
*/
*/
protected Resource[][] getResourcesToAdd(FileSet[] filesets,
protected ArchiveState getResourcesToAdd(FileSet[] filesets,
File zipFile,
File zipFile,
boolean needsUpdate)
boolean needsUpdate)
throws BuildException {
throws BuildException {
Resource[][] initialResources = grabResources(filesets);
Resource[][] initialResources = grabResources(filesets);
if (isEmpty(initialResources)) {
if (isEmpty(initialResources)) {
if (needsUpdate && doUpdate) {
/*
* This is a rather hairy case.
*
* One of our subclasses knows that we need to update the
* archive, but at the same time, there are no resources
* known to us that would need to be added. Only the
* subclass seems to know what's going on.
*
* This happens if <jar> detects that the manifest has changed,
* for example. The manifest is not part of any resources
* because of our support for inline <manifest>s.
*
* If we invoke createEmptyZip like Ant 1.5.2 did,
* we'll loose all stuff that has been in the original
* archive (bugzilla report 17780).
*/
return new ArchiveState(true, initialResources);
}
if (emptyBehavior.equals("skip")) {
if (emptyBehavior.equals("skip")) {
if (doUpdate) {
if (doUpdate) {
log(archiveType + " archive " + zipFile
log(archiveType + " archive " + zipFile
@@ -717,16 +744,18 @@ public class Zip extends MatchingTask {
// Create.
// Create.
createEmptyZip(zipFile);
createEmptyZip(zipFile);
}
}
return initialResources;
return new ArchiveState(needsUpdate, initialResources) ;
}
}
// initialResources is not empty
if (!zipFile.exists()) {
if (!zipFile.exists()) {
return initialResources;
return new ArchiveState(true, initialResources) ;
}
}
if (needsUpdate && !doUpdate) {
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
// we are recreating the archive, need all resources
return initialResources;
return new ArchiveState(true, initialResources) ;
}
}
Resource[][] newerResources = new Resource[filesets.length][];
Resource[][] newerResources = new Resource[filesets.length][];
@@ -794,10 +823,10 @@ public class Zip extends MatchingTask {
if (needsUpdate && !doUpdate) {
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
// we are recreating the archive, need all resources
return initialResources;
return new ArchiveState(true, initialResources) ;
}
}
return newerResources;
return new ArchiveState(needsUpdate, new erResources) ;
}
}
/**
/**
@@ -1096,4 +1125,28 @@ public class Zip extends MatchingTask {
return new String[] {"add", "preserve", "fail"};
return new String[] {"add", "preserve", "fail"};
}
}
}
}
/**
* Holds the up-to-date status and the out-of-date resources of
* the original archive.
*
* @since Ant 1.5.3
*/
public static class ArchiveState {
private boolean outOfDate;
private Resource[][] resourcesToAdd;
ArchiveState(boolean state, Resource[][] r) {
outOfDate = state;
resourcesToAdd = r;
}
public boolean isOutOfDate() {
return outOfDate;
}
public Resource[][] getResourcesToAdd() {
return resourcesToAdd;
}
}
}
}