@@ -66,6 +66,7 @@ import java.util.Hashtable;
import java.util.Stack;
import java.util.Stack;
import java.util.Vector;
import java.util.Vector;
import java.util.zip.CRC32;
import java.util.zip.CRC32;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipInputStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildException;
@@ -127,6 +128,7 @@ public class Zip extends MatchingTask {
protected boolean doubleFilePass = false;
protected boolean doubleFilePass = false;
protected boolean skipWriting = false;
protected boolean skipWriting = false;
private static FileUtils fileUtils = FileUtils.newFileUtils();
/**
/**
* 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
@@ -338,35 +340,31 @@ public class Zip extends MatchingTask {
}
}
}
}
// Create the scanners to pass to isUpToDate().
Vector dss = new Vector();
// collect filesets to pass them to getResourcesToAdd
Vector vfss = new Vector();
Vector vfss = new Vector();
if (baseDir != null) {
if (baseDir != null) {
dss.addElement(getDirectoryScanner(baseDir));
FileSet fs = new FileSet();
FileSet fs = (FileSet) getImplicitFileSet().clone();
fs.setDir(baseDir);
fs.setDir(baseDir);
vfss.addElement(fs);
vfss.addElement(fs);
}
}
for (int i = 0; i < filesets.size(); i++) {
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
FileSet fs = (FileSet) filesets.elementAt(i);
dss.addElement (fs.getDirectoryScanner(getProject()));
vfss.addElement(fs);
vfss.addElement(fs);
}
}
int dssSize = dss.size();
ResourceScanner[] scanners = new ResourceScanner[dssSize];
dss.copyInto(scanners);
FileSet [] fss = new FileSet[dssSize];
FileSet[] fss = new FileSet[vfss.size()];
vfss.copyInto(fss);
vfss.copyInto(fss);
boolean success = false;
boolean success = false;
try {
try {
Resource[][] addThem = 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
// can also handle empty archives
if (isUpToDate(scanners, fss, zipFile )) {
if (isEmpty(addThem )) {
return;
return;
}
}
if (doUpdate) {
if (doUpdate) {
FileUtils fileUtils = FileUtils.newFileUtils();
renamedFile =
renamedFile =
fileUtils.createTempFile("zip", ".tmp",
fileUtils.createTempFile("zip", ".tmp",
fileUtils.getParentFile(zipFile));
fileUtils.getParentFile(zipFile));
@@ -401,14 +399,13 @@ public class Zip extends MatchingTask {
}
}
initZipOutputStream(zOut);
initZipOutputStream(zOut);
// Add the implicit fileset to the archive.
if (baseDir != null) {
addFiles(getDirectoryScanner(baseDir), zOut, "", "",
ZipFileSet.DEFAULT_DIR_MODE,
ZipFileSet.DEFAULT_FILE_MODE);
}
// Add the explicit filesets to the archive.
// Add the explicit filesets to the archive.
addFiles(filesets, zOut);
for (int i = 0; i < fss.length; i++) {
if (addThem[i].length != 0) {
addResources(fss[i], addThem[i], zOut);
}
}
if (doUpdate) {
if (doUpdate) {
addingNewFiles = false;
addingNewFiles = false;
ZipFileSet oldFiles = new ZipFileSet();
ZipFileSet oldFiles = new ZipFileSet();
@@ -418,9 +415,10 @@ public class Zip extends MatchingTask {
PatternSet.NameEntry ne = oldFiles.createExclude();
PatternSet.NameEntry ne = oldFiles.createExclude();
ne.setName((String) addedFiles.elementAt(i));
ne.setName((String) addedFiles.elementAt(i));
}
}
Vector tmp = new Vector(1);
tmp.addElement(oldFiles);
addFiles(tmp, zOut);
addResources(oldFiles,
oldFiles.getDirectoryScanner(getProject())
.getIncludedFileResources(),
zOut);
}
}
finalizeZipOutputStream(zOut);
finalizeZipOutputStream(zOut);
@@ -481,127 +479,101 @@ public class Zip extends MatchingTask {
* Indicates if the task is adding new files into the archive as opposed to
* Indicates if the task is adding new files into the archive as opposed to
* copying back unchanged files from the backup copy
* copying back unchanged files from the backup copy
*/
*/
protected boolean isAddingNewFiles() {
protected final boolean isAddingNewFiles() {
return addingNewFiles;
return addingNewFiles;
}
}
/**
/**
* Add all files of the given FileScanner to the ZipOutputStream
* prependig the given prefix to each filename.
*
* <p>Ensure parent directories have been added as well.
*
* @deprecated use six-arg version instead.
*/
protected void addFiles(FileScanner scanner, ZipOutputStream zOut,
String prefix, String fullpath)
throws IOException {
addFiles(scanner, zOut, prefix, fullpath, ZipFileSet.DEFAULT_DIR_MODE,
ZipFileSet.DEFAULT_FILE_MODE);
}
/**
* Add all files of the given FileScanner to the ZipOutputStream
* prependig the given prefix to each filename.
* Add the given resources.
*
*
* <p>Ensure parent directories have been added as well.
* @param fileset may give additional information like fullpath or
* permissions.
* @param resources the resources to add
* @param zOut the stream to write to
*
*
* @since Ant 1.6
* @since Ant 1.6
*/
*/
protected void addFiles(FileScanner scanner, ZipOutputStream zOut,
String prefix, String fullpath, int dirMode,
int fileMode)
protected final void addResources(FileSet fileset, Resource[] resources,
ZipOutputStream zOut)
throws IOException {
throws IOException {
String prefix = "";
String fullpath = "";
int dirMode = ZipFileSet.DEFAULT_DIR_MODE;
int fileMode = ZipFileSet.DEFAULT_FILE_MODE;
ZipFileSet zfs = null;
if (fileset instanceof ZipFileSet) {
zfs = (ZipFileSet) fileset;
prefix = zfs.getPrefix();
fullpath = zfs.getFullpath();
dirMode = zfs.getDirMode();
fileMode = zfs.getDirMode();
}
if (prefix.length() > 0 && fullpath.length() > 0) {
if (prefix.length() > 0 && fullpath.length() > 0) {
throw new BuildException("Both prefix and fullpath attributes must"
throw new BuildException("Both prefix and fullpath attributes must"
+ " not be set on the same fileset.");
+ " not be set on the same fileset.");
}
}
File thisBaseDir = scanner.getBasedir();
// directories that matched include patterns
String[] dirs = scanner.getIncludedDirectories();
if (dirs.length > 0 && fullpath.length() > 0) {
if (resources.length != 1 && fullpath.length() > 0) {
throw new BuildException("fullpath attribute may only be specified"
throw new BuildException("fullpath attribute may only be specified"
+ " for filesets that specify a single"
+ " for filesets that specify a single"
+ " file.");
+ " file.");
}
}
for (int i = 0; i < dirs.length; i++) {
if ("".equals(dirs[i])) {
continue;
}
String name = dirs[i].replace(File.separatorChar, '/');
if (!name.endsWith("/")) {
name += "/";
}
addParentDirs(thisBaseDir, name, zOut, prefix, dirMode);
}
// 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.");
}
for (int i = 0; i < files.length; i++) {
File f = new File(thisBaseDir, files[i]);
if (fullpath.length() > 0) {
// Add this file at the specified location.
addParentDirs(null, fullpath, zOut, "", dirMode);
zipFile(f, zOut, fullpath, fileMode);
} else {
// Add this file with the specified prefix.
String name = files[i].replace(File.separatorChar, '/');
addParentDirs(thisBaseDir, name, zOut, prefix, dirMode);
zipFile(f, zOut, prefix + name, fileMode);
}
if (prefix.length() > 0
&& !prefix.endsWith("/")
&& !prefix.endsWith("\\")) {
prefix += "/";
}
}
}
protected void addZipEntries(ZipFileSet fs, DirectoryScanner ds,
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 must"
+ " not be set on the same fileset.");
}
ZipScanner zipScanner = (ZipScanner) ds;
File zipSrc = fs.getSrc();
ZipEntry entry;
java.util.zip.ZipEntry origEntry;
ZipInputStream in = null;
ZipFile zf = null;
try {
try {
in = new ZipInputStream(new FileInputStream(zipSrc));
while ((origEntry = in.getNextEntry()) != null) {
entry = new ZipEntry(origEntry);
String vPath = entry.getName();
if (zipScanner.match(vPath)) {
if (fullpath.length() > 0) {
addParentDirs(null, fullpath, zOut, "",
fs.getDirMode());
zipFile(in, zOut, fullpath, entry.getTime(), zipSrc,
fs.getFileMode());
} else {
addParentDirs(null, vPath, zOut, prefix,
fs.getDirMode());
if (!entry.isDirectory()) {
zipFile(in, zOut, prefix + vPath, entry.getTime(),
zipSrc, fs.getFileMode());
}
boolean dealingWithFiles = false;
File base = null;
if (zfs == null || zfs.getSrc() == null) {
dealingWithFiles = true;
base = fileset.getDir(getProject());
} else {
zf = new ZipFile(zfs.getSrc());
}
for (int i = 0; i < resources.length; i++) {
String name = null;
if (fullpath.length() > 0) {
name = fullpath;
} else {
name = resources[i].getName();
}
name = name.replace(File.separatorChar, '/');
if ("".equals(name)) {
continue;
}
if (resources[i].isDirectory() && ! name.endsWith("/")) {
name = name + "/";
}
addParentDirs(base, name, zOut, prefix, dirMode);
if (!resources[i].isDirectory() && dealingWithFiles) {
File f = fileUtils.resolveFile(base,
resources[i].getName());
zipFile(f, zOut, prefix + name, fileMode);
} else if (!resources[i].isDirectory()) {
java.util.zip.ZipEntry ze =
zf.getEntry(resources[i].getName());
if (ze != null) {
zipFile(zf.getInputStream(ze), zOut, prefix + name,
ze.getTime(), zfs.getSrc(), fileMode);
}
}
}
}
}
}
} finally {
} finally {
if (in != null) {
in.close();
if (zf != null) {
zf .close();
}
}
}
}
}
}
@@ -623,7 +595,7 @@ public class Zip extends MatchingTask {
/**
/**
* Create an empty zip file
* Create an empty zip file
*
*
* @return true if the file is then considered up to date.
* @return true for historic reasons
*/
*/
protected boolean createEmptyZip(File zipFile) {
protected boolean createEmptyZip(File zipFile) {
// In this case using java.util.zip will not work
// In this case using java.util.zip will not work
@@ -657,9 +629,12 @@ public class Zip extends MatchingTask {
return true;
return true;
}
}
/**
* @since Ant 1.6
*/
private synchronized ZipScanner getZipScanner() {
private synchronized ZipScanner getZipScanner() {
if (zs == null) {
if (zs == null) {
zs=new ZipScanner();
zs = new ZipScanner();
// set the task of the zip scanner so that it can log properly
// set the task of the zip scanner so that it can log properly
zs.setTask(this);
zs.setTask(this);
zs.setSrc(zipFile);
zs.setSrc(zipFile);
@@ -668,144 +643,149 @@ public class Zip extends MatchingTask {
}
}
/**
/**
* Check whether the archive is up-to-date; and handle behavior
* for empty archives.
* @param scanners list of prepared scanners containing files to archive
* Collect the resources that are newer than the corresponding
* entries (or missing) in the original archive.
*
* <p>If we are going to recreate the archive instead of updating
* it, all resources should be considered as new, if a single one
* is. Because of this, subclasses overriding this method must
* call <code>super.getResourcesToAdd</code> and indicate with the
* third arg if they already know that the archive is
* out-of-date.</p>
*
* @param filesets The filesets to grab resources from
* @param zipFile intended archive file (may or may not exist)
* @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
* @param needsUpdate whether we already know that the archive is
* out-of-date. Subclasses overriding this method are supposed to
* set this value correctly in their call to
* super.getResourcesToAdd.
* @return an array of resources to add for each fileset passed in.
*
* @exception BuildException if it likes
* @exception BuildException if it likes
*/
*/
protected boolean isUpToDate(ResourceScanner[] scanners,
FileSet[] fss, File zipFile)
protected Resource[][] getResourcesToAdd(FileSet[] filesets,
File zipFile,
boolean needsUpdate)
throws BuildException {
throws BuildException {
Resource[][] resourceNames = grabResources(scanners);
for (int counter = 0;counter < scanners.length; counter++){
for (int j=0; j < resourceNames[counter].length;j++) {
log("resource from scanner " + counter + " " + j + " name : "
+ resourceNames[counter][j].getName(), Project.MSG_DEBUG);
}
}
String[][] fileNames = grabFileNames(scanners);
File[] files = grabFiles(scanners, fileNames);
if (files.length == 0) {
Resource[][] initialResources = grabResources(filesets);
if (isEmpty(initialResources)) {
if (emptyBehavior.equals("skip")) {
if (emptyBehavior.equals("skip")) {
log("Warning: skipping " + archiveType + " archive " + zipFile +
" because no files were included.", Project.MSG_WARN);
return true ;
log("Warning: skipping " + archiveType + " archive "
+ zipFile + " because no files were included.",
Project.MSG_WARN);
} else if (emptyBehavior.equals("fail")) {
} else if (emptyBehavior.equals("fail")) {
throw new BuildException("Cannot create " + archiveType
throw new BuildException("Cannot create " + archiveType
+ " archive " + zipFile +
+ " archive " + zipFile +
": no files were included.", getLocation());
": no files were included.",
getLocation());
} else {
} else {
// Create.
// Create.
return createEmptyZip(zipFile);
}
} else {
for (int i = 0; i < files.length; ++i) {
if (files[i].equals(zipFile)) {
throw new BuildException("A zip file cannot include "
+ "itself", getLocation());
}
createEmptyZip(zipFile);
}
}
return initialResources;
}
if (!zipFile.exists()) {
return false;
}
if (!zipFile.exists()) {
return initialResources;
}
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return initialResources;
}
for (int i = 0; i < scanners.length; i++) {
boolean result=false;
FileNameMapper myMapper = new IdentityMapper();
if (fss[i] instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) fss[i];
if (zfs.getFullpath() != null
&& !zfs.getFullpath().equals("") ) {
// in this case all files from origin map to
// the fullPath attribute of the zipfileset at
// destination
MergingMapper fm = new MergingMapper();
fm.setTo(zfs.getFullpath());
myMapper = fm;
} else if (zfs.getPrefix() != null
&& !zfs.getPrefix().equals("")) {
GlobPatternMapper gm=new GlobPatternMapper();
gm.setFrom("*");
gm.setTo(zfs.getPrefix() + "*");
myMapper = gm;
Resource[][] newerResources = new Resource[filesets.length][];
for (int i = 0; i < filesets.length; i++) {
if (!(fileset instanceof ZipFileSet)
|| ((ZipFileSet) fileset).getSrc() == null) {
File base = filesets[i].getDir(getProject());
for (int j = 0; j < initialResources[i].length; j++) {
File resourceAsFile =
fileUtils.resolveFile(base,
initialResources[i][j].getName());
if (resourceAsFile.equals(zipFile)) {
throw new BuildException("A zip file cannot include "
+ "itself", getLocation());
}
}
}
}
Resource[] newerSources =
SourceSelector.selectOutOfDateSources(this,
resourceNames[i],
myMapper,
getZipScanner());
result = (newerSources.length == 0);
if (!result) {
return result;
}
}
}
}
}
return true;
}
protected static File[] grabFiles(FileScanner[] scanners) {
return grabFiles(scanners, grabFileNames(scanners));
}
protected static File[] grabFiles(FileScanner[] scanners,
String[][] fileNames) {
Vector files = new Vector();
for (int i = 0; i < fileNames.length; i++) {
File thisBaseDir = scanners[i].getBasedir();
for (int j = 0; j < fileNames[i].length; j++) {
files.addElement(new File(thisBaseDir, fileNames[i][j]));
for (int i = 0; i < filesets.length; i++) {
if (initialResources[i].length == 0) {
continue;
}
FileNameMapper myMapper = new IdentityMapper();
if (filesets[i] instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) filesets[i];
if (zfs.getFullpath() != null
&& !zfs.getFullpath().equals("") ) {
// in this case all files from origin map to
// the fullPath attribute of the zipfileset at
// destination
MergingMapper fm = new MergingMapper();
fm.setTo(zfs.getFullpath());
myMapper = fm;
} else if (zfs.getPrefix() != null
&& !zfs.getPrefix().equals("")) {
GlobPatternMapper gm=new GlobPatternMapper();
gm.setFrom("*");
String prefix = zfs.getPrefix();
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
prefix += "/";
}
gm.setTo(prefix + "*");
myMapper = gm;
}
}
newerResources[i] =
SourceSelector.selectOutOfDateSources(this,
initialResources[i],
myMapper,
getZipScanner());
needsUpdate = needsUpdate || (newerResources[i].length > 0);
if (needsUpdate && !doUpdate) {
// we will return initialResources anyway, no reason
// to scan further.
break;
}
}
}
}
File[] toret = new File[files.size()];
files.copyInto(toret);
return toret;
}
protected static String[][] grabFileNames(FileScanner[] scanners) {
String[][] result = new String[scanners.length][];
for (int i = 0; i < scanners.length; i++) {
String[] files = scanners[i].getIncludedFiles();
String[] dirs = scanners[i].getIncludedDirectories();
result[i] = new String[files.length + dirs.length];
System.arraycopy(files, 0, result[i], 0, files.length);
System.arraycopy(dirs, 0, result[i], files.length, dirs.length);
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return initialResources;
}
}
return result;
return newerResources;
}
}
/**
/**
* Fetch all included and not excluded resources from the sets.
*
* <p>Included directories will preceede included files.</p>
*
*
* @param scanners here are expected ResourceScanner arguments
* @return double dimensional array of resources
* @since Ant 1.6
*/
*/
protected static Resource[][] grabResources(ResourceScanner[] scanners) {
Resource[][] result = new Resource[scanners.length][];
for (int i = 0; i < scanners.length; i++) {
Resource[] files = scanners[i].getIncludedFileResources();
Resource[] directories =
scanners[i].getIncludedDirectoryResources();
protected Resource[][] grabResources(FileSet[] fileset s) {
Resource[][] result = new Resource[fileset s.length][];
for (int i = 0; i < fileset s.length; i++) {
ResourceScanner rs = filesets[i].getDirectoryScanner(getProject() );
Resource[] files = rs.getIncludedFileResources();
Resource[] directories = rs .getIncludedDirectoryResources();
result[i] = new Resource[files.length + directories.length];
result[i] = new Resource[files.length + directories.length];
System.arraycopy(files, 0, result[i], 0, fil es.length);
System.arraycopy(directories, 0, result[i], fil es.length,
directori es.length);
System.arraycopy(directories, 0, result[i], 0, directori es.length);
System.arraycopy(files, 0, result[i], directori es.length,
fil es.length);
}
}
return result;
return result;
}
}
/**
* @deprecated use four-arg version instead.
*/
protected void zipDir(File dir, ZipOutputStream zOut, String vPath)
throws IOException {
zipDir(dir, zOut, vPath, ZipFileSet.DEFAULT_DIR_MODE);
}
/**
/**
* @since Ant 1.6
* @since Ant 1.6
*/
*/
@@ -841,20 +821,20 @@ public class Zip extends MatchingTask {
}
}
/**
/**
* @deprecated use six-arg version instead .
*/
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
long lastModified, File file)
throws IOException {
zipFile(in, zOut, vPath, lastModified, file,
ZipFileSet.DEFAULT_FILE_MODE);
}
/* *
* Adds a new entry to the archive, takes care of duplicates as well .
*
* @param in the stream to read data for the entry from.
* @param zOut the stream to write to.
* @param vPath the name this entry shall have in the archive.
* @param lastModified last modification time for the entry.
* @param fromArchive the original archive we are copying this
* entry from, will be null if we are not copying from an archive.
* @param mode the Unix permissions to set.
*
* @since Ant 1.6
* @since Ant 1.6
*/
*/
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
protected void zipFile(InputStream in, ZipOutputStream zOut, String vPath,
long lastModified, File fil e, int mode)
long lastModified, File fromArchiv e, int mode)
throws IOException {
throws IOException {
if (entries.contains(vPath)) {
if (entries.contains(vPath)) {
@@ -939,17 +919,18 @@ public class Zip extends MatchingTask {
}
}
/**
/**
* @deprecated use six-arg version instead.
*/
protected void zipFile(File file, ZipOutputStream zOut, String vPath)
throws IOException {
zipFile(file, zOut, vPath, ZipFileSet.DEFAULT_FILE_MODE);
}
/**
* Method that gets called when adding from java.io.File instances.
*
* <p>This implementation delegates to the six-arg version.</p>
*
* @param file the file to add to the archive
* @param zOut the stream to write to
* @param vPath the name this entry shall have in the archive
* @param mode the Unix permissions to set.
*
* @since Ant 1.6
* @since Ant 1.6
*/
*/
protected void zipFile(File file, ZipOutputStream zOut, String vPath,
protected void zipFile(File file, ZipOutputStream zOut, String vPath,
int mode)
int mode)
throws IOException {
throws IOException {
if (file.equals(zipFile)) {
if (file.equals(zipFile)) {
@@ -966,24 +947,14 @@ public class Zip extends MatchingTask {
}
}
}
}
/**
* @deprecated use five-arg version instead.
*/
protected void addParentDirs(File baseDir, String entry,
ZipOutputStream zOut, String prefix)
throws IOException {
addParentDirs(baseDir, entry, zOut, prefix,
ZipFileSet.DEFAULT_DIR_MODE);
}
/**
/**
* Ensure all parent dirs of a given entry have been added.
* Ensure all parent dirs of a given entry have been added.
*
*
* @since Ant 1.6
* @since Ant 1.6
*/
*/
protected void addParentDirs(File baseDir, String entry,
ZipOutputStream zOut, String prefix,
int dirMode)
protected final void addParentDirs(File baseDir, String entry,
ZipOutputStream zOut, String prefix,
int dirMode)
throws IOException {
throws IOException {
if (!doFilesonly) {
if (!doFilesonly) {
Stack directories = new Stack();
Stack directories = new Stack();
@@ -1010,55 +981,6 @@ public class Zip extends MatchingTask {
}
}
}
}
/**
* Iterate over the given Vector of (zip)filesets and add
* all files to the ZipOutputStream using the given prefix
* or fullpath.
*/
protected void addFiles(Vector filesets, ZipOutputStream zOut)
throws IOException {
// Add each fileset in the Vector.
for (int i = 0; i < filesets.size(); i++) {
FileSet fs = (FileSet) filesets.elementAt(i);
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
String prefix = "";
String fullpath = "";
int fileMode = ZipFileSet.DEFAULT_FILE_MODE;
int dirMode = ZipFileSet.DEFAULT_DIR_MODE;
if (fs instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) fs;
prefix = zfs.getPrefix();
fullpath = zfs.getFullpath();
fileMode = zfs.getFileMode();
dirMode = zfs.getDirMode();
}
if (prefix.length() > 0
&& !prefix.endsWith("/")
&& !prefix.endsWith("\\")) {
prefix += "/";
}
// Need to manually add either fullpath's parent directory, or
// the prefix directory, to the archive.
if (prefix.length() > 0) {
addParentDirs(null, prefix, zOut, "", dirMode);
zipDir(null, zOut, prefix, dirMode);
} else if (fullpath.length() > 0) {
addParentDirs(null, fullpath, zOut, "", dirMode);
}
if (fs instanceof ZipFileSet
&& ((ZipFileSet) fs).getSrc() != null) {
addZipEntries((ZipFileSet) fs, ds, zOut, prefix, fullpath);
} else {
// Add the fileset.
addFiles(ds, zOut, prefix, fullpath, dirMode, fileMode);
}
}
}
/**
/**
* Do any clean up necessary to allow this instance to be used again.
* Do any clean up necessary to allow this instance to be used again.
*
*
@@ -1109,6 +1031,20 @@ public class Zip extends MatchingTask {
encoding = null;
encoding = null;
}
}
/**
* @return true if all individual arrays are empty
*
* @since Ant 1.6
*/
protected final static boolean isEmpty(Resource[][] r) {
for (int i = 0; i < r.length; i++) {
if (r[i].length > 0) {
return false;
}
}
return true;
}
/**
/**
* Possible behaviors when a duplicate file is added:
* Possible behaviors when a duplicate file is added:
* "add", "preserve" or "fail"
* "add", "preserve" or "fail"