Zippublic class Zip extends MatchingTask
Fields Summary |
---|
protected File | zipFile | private org.apache.tools.ant.types.ZipScanner | zs | private File | baseDir | protected Hashtable | entries | private Vector | groupfilesets | private Vector | filesetsFromGroupfilesets | protected String | duplicate | private boolean | doCompress | private boolean | doUpdate | private boolean | savedDoUpdate | private boolean | doFilesonly | protected String | archiveType | private static final long | EMPTY_CRC | protected String | emptyBehavior | private Vector | resources | protected Hashtable | addedDirs | private Vector | addedFiles | protected boolean | doubleFilePass | protected boolean | skipWriting | private static final org.apache.tools.ant.util.FileUtils | FILE_UTILS | private boolean | addingNewFilestrue when we are adding new files into the Zip file, as opposed
to adding back the unchanged files | private String | encodingEncoding to use for filenames, defaults to the platform's
default encoding. | private boolean | keepCompressionWhether the original compression of entries coming from a ZIP
archive should be kept (for example when updating an archive). | private boolean | roundUpWhether the file modification times will be rounded up to the
next even number of seconds. | private String | commentComment for the archive. | private int | level |
Methods Summary |
---|
public void | add(org.apache.tools.ant.types.ResourceCollection a)Add a collection of resources to be archived.
resources.add(a);
| public void | addFileset(org.apache.tools.ant.types.FileSet set)Adds a set of files.
add(set);
| protected final void | addParentDirs(java.io.File baseDir, java.lang.String entry, org.apache.tools.zip.ZipOutputStream zOut, java.lang.String prefix, int dirMode)Ensure all parent dirs of a given entry have been added.
if (!doFilesonly) {
Stack directories = new Stack();
int slashPos = entry.length();
while ((slashPos = entry.lastIndexOf('/", slashPos - 1)) != -1) {
String dir = entry.substring(0, slashPos + 1);
if (addedDirs.get(prefix + dir) != null) {
break;
}
directories.push(dir);
}
while (!directories.isEmpty()) {
String dir = (String) directories.pop();
File f = null;
if (baseDir != null) {
f = new File(baseDir, dir);
} else {
f = new File(dir);
}
zipDir(f, zOut, prefix + dir, dirMode);
}
}
| protected final void | addResources(org.apache.tools.ant.types.FileSet fileset, org.apache.tools.ant.types.Resource[] resources, org.apache.tools.zip.ZipOutputStream zOut)Add the given resources.
String prefix = "";
String fullpath = "";
int dirMode = ArchiveFileSet.DEFAULT_DIR_MODE;
int fileMode = ArchiveFileSet.DEFAULT_FILE_MODE;
ArchiveFileSet zfs = null;
if (fileset instanceof ArchiveFileSet) {
zfs = (ArchiveFileSet) fileset;
prefix = zfs.getPrefix(getProject());
fullpath = zfs.getFullpath(getProject());
dirMode = zfs.getDirMode(getProject());
fileMode = zfs.getFileMode(getProject());
}
if (prefix.length() > 0 && fullpath.length() > 0) {
throw new BuildException("Both prefix and fullpath attributes must"
+ " not be set on the same fileset.");
}
if (resources.length != 1 && fullpath.length() > 0) {
throw new BuildException("fullpath attribute may only be specified"
+ " for filesets that specify a single"
+ " file.");
}
if (prefix.length() > 0) {
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
prefix += "/";
}
addParentDirs(null, prefix, zOut, "", dirMode);
}
ZipFile zf = null;
try {
boolean dealingWithFiles = false;
File base = null;
if (zfs == null || zfs.getSrc(getProject()) == null) {
dealingWithFiles = true;
base = fileset.getDir(getProject());
} else if (zfs instanceof ZipFileSet) {
zf = new ZipFile(zfs.getSrc(getProject()), encoding);
}
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 + "/";
}
if (!doFilesonly && !dealingWithFiles
&& resources[i].isDirectory()
&& !zfs.hasDirModeBeenSet()) {
int nextToLastSlash = name.lastIndexOf("/",
name.length() - 2);
if (nextToLastSlash != -1) {
addParentDirs(base, name.substring(0,
nextToLastSlash + 1),
zOut, prefix, dirMode);
}
if (zf != null) {
ZipEntry ze = zf.getEntry(resources[i].getName());
addParentDirs(base, name, zOut, prefix,
ze.getUnixMode());
} else {
ArchiveResource tr = (ArchiveResource) resources[i];
addParentDirs(base, name, zOut, prefix,
tr.getMode());
}
} else {
addParentDirs(base, name, zOut, prefix, dirMode);
}
if (!resources[i].isDirectory() && dealingWithFiles) {
File f = FILE_UTILS.resolveFile(base,
resources[i].getName());
zipFile(f, zOut, prefix + name, fileMode);
} else if (!resources[i].isDirectory()) {
if (zf != null) {
ZipEntry ze = zf.getEntry(resources[i].getName());
if (ze != null) {
boolean oldCompress = doCompress;
if (keepCompression) {
doCompress = (ze.getMethod() == ZipEntry.DEFLATED);
}
try {
zipFile(zf.getInputStream(ze), zOut, prefix + name,
ze.getTime(), zfs.getSrc(getProject()),
zfs.hasFileModeBeenSet() ? fileMode
: ze.getUnixMode());
} finally {
doCompress = oldCompress;
}
}
} else {
ArchiveResource tr = (ArchiveResource) resources[i];
InputStream is = null;
try {
is = tr.getInputStream();
zipFile(is, zOut, prefix + name,
resources[i].getLastModified(),
zfs.getSrc(getProject()),
zfs.hasFileModeBeenSet() ? fileMode
: tr.getMode());
} finally {
FileUtils.close(is);
}
}
}
}
} finally {
if (zf != null) {
zf.close();
}
}
| protected final void | addResources(org.apache.tools.ant.types.ResourceCollection rc, org.apache.tools.ant.types.Resource[] resources, org.apache.tools.zip.ZipOutputStream zOut)Add the given resources.
if (rc instanceof FileSet) {
addResources((FileSet) rc, resources, zOut);
return;
}
for (int i = 0; i < resources.length; i++) {
String name = resources[i].getName().replace(File.separatorChar,
'/");
if ("".equals(name)) {
continue;
}
if (resources[i].isDirectory() && doFilesonly) {
continue;
}
File base = null;
if (resources[i] instanceof FileResource) {
base = ((FileResource) resources[i]).getBaseDir();
}
if (resources[i].isDirectory()) {
if (!name.endsWith("/")) {
name = name + "/";
}
}
addParentDirs(base, name, zOut, "",
ArchiveFileSet.DEFAULT_DIR_MODE);
if (!resources[i].isDirectory()) {
if (resources[i] instanceof FileResource) {
File f = ((FileResource) resources[i]).getFile();
zipFile(f, zOut, name, ArchiveFileSet.DEFAULT_FILE_MODE);
} else {
InputStream is = null;
try {
is = resources[i].getInputStream();
zipFile(is, zOut, name,
resources[i].getLastModified(),
null, ArchiveFileSet.DEFAULT_FILE_MODE);
} finally {
FileUtils.close(is);
}
}
}
}
| public void | addZipGroupFileset(org.apache.tools.ant.types.FileSet set)Adds a group of zip files.
groupfilesets.addElement(set);
| public void | addZipfileset(org.apache.tools.ant.types.ZipFileSet set)Adds a set of files that can be
read from an archive and be given a prefix/fullpath.
add(set);
| protected void | cleanUp()Do any clean up necessary to allow this instance to be used again.
When we get here, the Zip file has been closed and all we
need to do is to reset some globals.
This method will only reset globals that have been changed
during execute(), it will not alter the attributes or nested
child elements. If you want to reset the instance so that you
can later zip a completely different set of files, you must use
the reset method.
addedDirs.clear();
addedFiles.removeAllElements();
entries.clear();
addingNewFiles = false;
doUpdate = savedDoUpdate;
Enumeration e = filesetsFromGroupfilesets.elements();
while (e.hasMoreElements()) {
ZipFileSet zf = (ZipFileSet) e.nextElement();
resources.removeElement(zf);
}
filesetsFromGroupfilesets.removeAllElements();
| protected boolean | createEmptyZip(java.io.File zipFile)Create an empty zip file
// 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);
OutputStream os = null;
try {
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.getMessage() + ")", ioe,
getLocation());
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
//ignore
}
}
}
return true;
| public void | execute()validate and build
if (doubleFilePass) {
skipWriting = true;
executeMain();
skipWriting = false;
executeMain();
} else {
executeMain();
}
| public void | executeMain()Build the zip file.
This is called twice if doubleFilePass is true.
if (baseDir == null && resources.size() == 0
&& groupfilesets.size() == 0 && "zip".equals(archiveType)) {
throw new BuildException("basedir attribute must be set, "
+ "or at least one "
+ "resource collection must be given!");
}
if (zipFile == null) {
throw new BuildException("You must specify the "
+ archiveType + " file to create!");
}
if (zipFile.exists() && !zipFile.isFile()) {
throw new BuildException(zipFile + " is not a file.");
}
if (zipFile.exists() && !zipFile.canWrite()) {
throw new BuildException(zipFile + " is read-only.");
}
// Renamed version of original file, if it exists
File renamedFile = null;
addingNewFiles = true;
// Whether or not an actual update is required -
// we don't need to update if the original file doesn't exist
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
for (int i = 0; i < groupfilesets.size(); i++) {
log("Processing groupfileset ", Project.MSG_VERBOSE);
FileSet fs = (FileSet) groupfilesets.elementAt(i);
FileScanner scanner = fs.getDirectoryScanner(getProject());
String[] files = scanner.getIncludedFiles();
File basedir = scanner.getBasedir();
for (int j = 0; j < files.length; j++) {
log("Adding file " + files[j] + " to fileset",
Project.MSG_VERBOSE);
ZipFileSet zf = new ZipFileSet();
zf.setProject(getProject());
zf.setSrc(new File(basedir, files[j]));
add(zf);
filesetsFromGroupfilesets.addElement(zf);
}
}
// collect filesets to pass them to getResourcesToAdd
Vector vfss = new Vector();
if (baseDir != null) {
FileSet fs = (FileSet) getImplicitFileSet().clone();
fs.setDir(baseDir);
vfss.addElement(fs);
}
for (int i = 0; i < resources.size(); i++) {
ResourceCollection rc = (ResourceCollection) resources.elementAt(i);
vfss.addElement(rc);
}
ResourceCollection[] fss = new ResourceCollection[vfss.size()];
vfss.copyInto(fss);
boolean success = false;
try {
// can also handle empty archives
ArchiveState state = getResourcesToAdd(fss, zipFile, false);
// quick exit if the target is up to date
if (!state.isOutOfDate()) {
return;
}
if (!zipFile.exists() && state.isWithoutAnyResources()) {
createEmptyZip(zipFile);
return;
}
Resource[][] addThem = state.getResourcesToAdd();
if (doUpdate) {
renamedFile =
FILE_UTILS.createTempFile("zip", ".tmp",
zipFile.getParentFile());
renamedFile.deleteOnExit();
try {
FILE_UTILS.rename(zipFile, renamedFile);
} catch (SecurityException e) {
throw new BuildException(
"Not allowed to rename old file ("
+ zipFile.getAbsolutePath()
+ ") to temporary file");
} catch (IOException e) {
throw new BuildException(
"Unable to rename old file ("
+ zipFile.getAbsolutePath()
+ ") to temporary file");
}
}
String action = doUpdate ? "Updating " : "Building ";
log(action + archiveType + ": " + zipFile.getAbsolutePath());
ZipOutputStream zOut = null;
try {
if (!skipWriting) {
zOut = new ZipOutputStream(zipFile);
zOut.setEncoding(encoding);
zOut.setMethod(doCompress
? ZipOutputStream.DEFLATED : ZipOutputStream.STORED);
zOut.setLevel(level);
}
initZipOutputStream(zOut);
// Add the explicit resource collections to the archive.
for (int i = 0; i < fss.length; i++) {
if (addThem[i].length != 0) {
addResources(fss[i], addThem[i], zOut);
}
}
if (doUpdate) {
addingNewFiles = false;
ZipFileSet oldFiles = new ZipFileSet();
oldFiles.setProject(getProject());
oldFiles.setSrc(renamedFile);
oldFiles.setDefaultexcludes(false);
for (int i = 0; i < addedFiles.size(); i++) {
PatternSet.NameEntry ne = oldFiles.createExclude();
ne.setName((String) addedFiles.elementAt(i));
}
DirectoryScanner ds =
oldFiles.getDirectoryScanner(getProject());
((ZipScanner) ds).setEncoding(encoding);
String[] f = ds.getIncludedFiles();
Resource[] r = new Resource[f.length];
for (int i = 0; i < f.length; i++) {
r[i] = ds.getResource(f[i]);
}
if (!doFilesonly) {
String[] d = ds.getIncludedDirectories();
Resource[] dr = new Resource[d.length];
for (int i = 0; i < d.length; i++) {
dr[i] = ds.getResource(d[i]);
}
Resource[] tmp = r;
r = new Resource[tmp.length + dr.length];
System.arraycopy(dr, 0, r, 0, dr.length);
System.arraycopy(tmp, 0, r, dr.length, tmp.length);
}
addResources(oldFiles, r, zOut);
}
if (zOut != null) {
zOut.setComment(comment);
}
finalizeZipOutputStream(zOut);
// If we've been successful on an update, delete the
// temporary file
if (doUpdate) {
if (!renamedFile.delete()) {
log ("Warning: unable to delete temporary file "
+ renamedFile.getName(), Project.MSG_WARN);
}
}
success = true;
} finally {
// Close the output stream.
try {
if (zOut != null) {
zOut.close();
}
} catch (IOException ex) {
// If we're in this finally clause because of an
// exception, we don't really care if there's an
// exception when closing the stream. E.g. if it
// throws "ZIP file must have at least one entry",
// because an exception happened before we added
// any files, then we must swallow this
// exception. Otherwise, the error that's reported
// will be the close() error, which is not the
// real cause of the problem.
if (success) {
throw ex;
}
}
}
} catch (IOException ioe) {
String msg = "Problem creating " + archiveType + ": "
+ ioe.getMessage();
// delete a bogus ZIP file (but only if it's not the original one)
if ((!doUpdate || renamedFile != null) && !zipFile.delete()) {
msg += " (and the archive is probably corrupt but I could not "
+ "delete it)";
}
if (doUpdate && renamedFile != null) {
try {
FILE_UTILS.rename(renamedFile, zipFile);
} catch (IOException e) {
msg += " (and I couldn't rename the temporary file "
+ renamedFile.getName() + " back)";
}
}
throw new BuildException(msg, ioe, getLocation());
} finally {
cleanUp();
}
| protected void | finalizeZipOutputStream(org.apache.tools.zip.ZipOutputStream zOut)method for subclasses to override
| public java.lang.String | getComment()Comment of the archive
return comment;
| public java.io.File | getDestFile()The file to create.
return zipFile;
| public java.lang.String | getEncoding()Encoding to use for filenames.
return encoding;
| public int | getLevel()Get the compression level.
return level;
| protected org.apache.tools.ant.taskdefs.Zip$ArchiveState | getNonFileSetResourcesToAdd(org.apache.tools.ant.types.ResourceCollection[] rcs, java.io.File zipFile, boolean needsUpdate)Collect the resources that are newer than the corresponding
entries (or missing) in the original archive.
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 super.getResourcesToAdd and indicate with the
third arg if they already know that the archive is
out-of-date.
/*
* Backwards compatibility forces us to repeat the logic of
* getResourcesToAdd(FileSet[], ...) here once again.
*/
Resource[][] initialResources = grabNonFileSetResources(rcs);
if (isEmpty(initialResources)) {
// no emptyBehavior handling since the FileSet version
// will take care of it.
return new ArchiveState(needsUpdate, initialResources);
}
// initialResources is not empty
if (!zipFile.exists()) {
return new ArchiveState(true, initialResources);
}
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return new ArchiveState(true, initialResources);
}
Resource[][] newerResources = new Resource[rcs.length][];
for (int i = 0; i < rcs.length; i++) {
if (initialResources[i].length == 0) {
newerResources[i] = new Resource[] {};
continue;
}
for (int j = 0; j < initialResources[i].length; j++) {
if (initialResources[i][j] instanceof FileResource
&& zipFile.equals(((FileResource)
initialResources[i][j]).getFile())) {
throw new BuildException("A zip file cannot include "
+ "itself", getLocation());
}
}
Resource[] rs = initialResources[i];
if (doFilesonly) {
rs = selectFileResources(rs);
}
newerResources[i] =
ResourceUtils.selectOutOfDateSources(this,
rs,
new IdentityMapper(),
getZipScanner());
needsUpdate = needsUpdate || (newerResources[i].length > 0);
if (needsUpdate && !doUpdate) {
// we will return initialResources anyway, no reason
// to scan further.
break;
}
}
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return new ArchiveState(true, initialResources);
}
return new ArchiveState(needsUpdate, newerResources);
| protected org.apache.tools.ant.taskdefs.Zip$ArchiveState | getResourcesToAdd(org.apache.tools.ant.types.ResourceCollection[] rcs, java.io.File zipFile, boolean needsUpdate)Collect the resources that are newer than the corresponding
entries (or missing) in the original archive.
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 super.getResourcesToAdd and indicate with the
third arg if they already know that the archive is
out-of-date.
This method first delegates to getNonFileSetResourceToAdd
and then invokes the FileSet-arg version. All this to keep
backwards compatibility for subclasses that don't know how to
deal with non-FileSet ResourceCollections.
ArrayList filesets = new ArrayList();
ArrayList rest = new ArrayList();
for (int i = 0; i < rcs.length; i++) {
if (rcs[i] instanceof FileSet) {
filesets.add(rcs[i]);
} else {
rest.add(rcs[i]);
}
}
ResourceCollection[] rc = (ResourceCollection[])
rest.toArray(new ResourceCollection[rest.size()]);
ArchiveState as = getNonFileSetResourcesToAdd(rc, zipFile,
needsUpdate);
FileSet[] fs = (FileSet[]) filesets.toArray(new FileSet[filesets
.size()]);
ArchiveState as2 = getResourcesToAdd(fs, zipFile, as.isOutOfDate());
if (!as.isOutOfDate() && as2.isOutOfDate()) {
/*
* Bad luck.
*
* There are resources in the filesets that make the
* archive out of date, but not in the non-fileset
* resources. We need to rescan the non-FileSets to grab
* all of them now.
*/
as = getNonFileSetResourcesToAdd(rc, zipFile, true);
}
Resource[][] toAdd = new Resource[rcs.length][];
int fsIndex = 0;
int restIndex = 0;
for (int i = 0; i < rcs.length; i++) {
if (rcs[i] instanceof FileSet) {
toAdd[i] = as2.getResourcesToAdd()[fsIndex++];
} else {
toAdd[i] = as.getResourcesToAdd()[restIndex++];
}
}
return new ArchiveState(as2.isOutOfDate(), toAdd);
| protected org.apache.tools.ant.taskdefs.Zip$ArchiveState | getResourcesToAdd(org.apache.tools.ant.types.FileSet[] filesets, java.io.File zipFile, boolean needsUpdate)Collect the resources that are newer than the corresponding
entries (or missing) in the original archive.
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 super.getResourcesToAdd and indicate with the
third arg if they already know that the archive is
out-of-date.
Resource[][] initialResources = grabResources(filesets);
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 (doUpdate) {
log(archiveType + " archive " + zipFile
+ " not updated because no new files were included.",
Project.MSG_VERBOSE);
} else {
log("Warning: skipping " + archiveType + " archive "
+ zipFile + " because no files were included.",
Project.MSG_WARN);
}
} else if (emptyBehavior.equals("fail")) {
throw new BuildException("Cannot create " + archiveType
+ " archive " + zipFile
+ ": no files were included.",
getLocation());
} else {
// Create.
if (!zipFile.exists()) {
needsUpdate = true;
}
}
return new ArchiveState(needsUpdate, initialResources);
}
// initialResources is not empty
if (!zipFile.exists()) {
return new ArchiveState(true, initialResources);
}
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return new ArchiveState(true, initialResources);
}
Resource[][] newerResources = new Resource[filesets.length][];
for (int i = 0; i < filesets.length; i++) {
if (!(fileset instanceof ZipFileSet)
|| ((ZipFileSet) fileset).getSrc(getProject()) == null) {
File base = filesets[i].getDir(getProject());
for (int j = 0; j < initialResources[i].length; j++) {
File resourceAsFile =
FILE_UTILS.resolveFile(base,
initialResources[i][j].getName());
if (resourceAsFile.equals(zipFile)) {
throw new BuildException("A zip file cannot include "
+ "itself", getLocation());
}
}
}
}
for (int i = 0; i < filesets.length; i++) {
if (initialResources[i].length == 0) {
newerResources[i] = new Resource[] {};
continue;
}
FileNameMapper myMapper = new IdentityMapper();
if (filesets[i] instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) filesets[i];
if (zfs.getFullpath(getProject()) != null
&& !zfs.getFullpath(getProject()).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(getProject()));
myMapper = fm;
} else if (zfs.getPrefix(getProject()) != null
&& !zfs.getPrefix(getProject()).equals("")) {
GlobPatternMapper gm = new GlobPatternMapper();
gm.setFrom("*");
String prefix = zfs.getPrefix(getProject());
if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
prefix += "/";
}
gm.setTo(prefix + "*");
myMapper = gm;
}
}
Resource[] resources = initialResources[i];
if (doFilesonly) {
resources = selectFileResources(resources);
}
newerResources[i] =
ResourceUtils.selectOutOfDateSources(this,
resources,
myMapper,
getZipScanner());
needsUpdate = needsUpdate || (newerResources[i].length > 0);
if (needsUpdate && !doUpdate) {
// we will return initialResources anyway, no reason
// to scan further.
break;
}
}
if (needsUpdate && !doUpdate) {
// we are recreating the archive, need all resources
return new ArchiveState(true, initialResources);
}
return new ArchiveState(needsUpdate, newerResources);
| private synchronized org.apache.tools.ant.types.ZipScanner | getZipScanner()
if (zs == null) {
zs = new ZipScanner();
zs.setEncoding(encoding);
zs.setSrc(zipFile);
}
return zs;
| protected org.apache.tools.ant.types.Resource[][] | grabNonFileSetResources(org.apache.tools.ant.types.ResourceCollection[] rcs)Fetch all included and not excluded resources from the collections.
Included directories will precede included files.
Resource[][] result = new Resource[rcs.length][];
for (int i = 0; i < rcs.length; i++) {
Iterator iter = rcs[i].iterator();
ArrayList rs = new ArrayList();
int lastDir = 0;
while (iter.hasNext()) {
Resource r = (Resource) iter.next();
if (r.isExists()) {
if (r.isDirectory()) {
rs.add(lastDir++, r);
} else {
rs.add(r);
}
}
}
result[i] = (Resource[]) rs.toArray(new Resource[rs.size()]);
}
return result;
| protected org.apache.tools.ant.types.Resource[][] | grabResources(org.apache.tools.ant.types.FileSet[] filesets)Fetch all included and not excluded resources from the sets.
Included directories will precede included files.
Resource[][] result = new Resource[filesets.length][];
for (int i = 0; i < filesets.length; i++) {
boolean skipEmptyNames = true;
if (filesets[i] instanceof ZipFileSet) {
ZipFileSet zfs = (ZipFileSet) filesets[i];
skipEmptyNames = zfs.getPrefix(getProject()).equals("")
&& zfs.getFullpath(getProject()).equals("");
}
DirectoryScanner rs =
filesets[i].getDirectoryScanner(getProject());
if (rs instanceof ZipScanner) {
((ZipScanner) rs).setEncoding(encoding);
}
Vector resources = new Vector();
if (!doFilesonly) {
String[] directories = rs.getIncludedDirectories();
for (int j = 0; j < directories.length; j++) {
if (!"".equals(directories[j]) || !skipEmptyNames) {
resources.addElement(rs.getResource(directories[j]));
}
}
}
String[] files = rs.getIncludedFiles();
for (int j = 0; j < files.length; j++) {
if (!"".equals(files[j]) || !skipEmptyNames) {
resources.addElement(rs.getResource(files[j]));
}
}
result[i] = new Resource[resources.size()];
resources.copyInto(result[i]);
}
return result;
| protected void | initZipOutputStream(org.apache.tools.zip.ZipOutputStream zOut)method for subclasses to override
| protected final boolean | isAddingNewFiles()Indicates if the task is adding new files into the archive as opposed to
copying back unchanged files from the backup copy
return addingNewFiles;
| public boolean | isCompress()Whether we want to compress the files or only store them;
return doCompress;
| protected static final boolean | isEmpty(org.apache.tools.ant.types.Resource[][] r)Check is the resource arrays are empty.
for (int i = 0; i < r.length; i++) {
if (r[i].length > 0) {
return false;
}
}
return true;
| public boolean | isInUpdateMode()Are we updating an existing archive?
return doUpdate;
| public void | reset()Makes this instance reset all attributes to their default
values and forget all children.
resources.removeAllElements();
zipFile = null;
baseDir = null;
groupfilesets.removeAllElements();
duplicate = "add";
archiveType = "zip";
doCompress = true;
emptyBehavior = "skip";
doUpdate = false;
doFilesonly = false;
encoding = null;
| protected org.apache.tools.ant.types.Resource[] | selectFileResources(org.apache.tools.ant.types.Resource[] orig)Drops all non-file resources from the given array.
if (orig.length == 0) {
return orig;
}
Vector v = new Vector(orig.length);
for (int i = 0; i < orig.length; i++) {
if (!orig[i].isDirectory()) {
v.addElement(orig[i]);
} else {
log("Ignoring directory " + orig[i].getName()
+ " as only files will be added.", Project.MSG_VERBOSE);
}
}
if (v.size() != orig.length) {
Resource[] r = new Resource[v.size()];
v.copyInto(r);
return r;
}
return orig;
| public void | setBasedir(java.io.File baseDir)Directory from which to archive files; optional.
this.baseDir = baseDir;
| public void | setComment(java.lang.String comment)Comment to use for archive.
this.comment = comment;
| public void | setCompress(boolean c)Whether we want to compress the files or only store them;
optional, default=true;
doCompress = c;
| public void | setDestFile(java.io.File destFile)The file to create; required.
this.zipFile = destFile;
| public void | setDuplicate(org.apache.tools.ant.taskdefs.Zip$Duplicate df)Sets behavior for when a duplicate file is about to be added -
one of add , preserve or fail .
Possible values are: add (keep both
of the files); preserve (keep the first version
of the file found); fail halt a problem
Default for zip tasks is add
duplicate = df.getValue();
| public void | setEncoding(java.lang.String encoding)Encoding to use for filenames, defaults to the platform's
default encoding.
For a list of possible values see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html.
this.encoding = encoding;
| public void | setFile(java.io.File file)This is the name/location of where to
create the file.
setDestFile(file);
| public void | setFilesonly(boolean f)If true, emulate Sun's jar utility by not adding parent directories;
optional, defaults to false.
doFilesonly = f;
| public void | setKeepCompression(boolean keep)Whether the original compression of entries coming from a ZIP
archive should be kept (for example when updating an archive).
Default is false.
keepCompression = keep;
| public void | setLevel(int level)Set the compression level to use. Default is
ZipOutputStream.DEFAULT_COMPRESSION.
this.level = level;
| public void | setRoundUp(boolean r)Whether the file modification times will be rounded up to the
next even number of seconds.
Zip archives store file modification times with a
granularity of two seconds, so the times will either be rounded
up or down. If you round down, the archive will always seem
out-of-date when you rerun the task, so the default is to round
up. Rounding up may lead to a different type of problems like
JSPs inside a web archive that seem to be slightly more recent
than precompiled pages, rendering precompilation useless.
roundUp = r;
| public void | setUpdate(boolean c)If true, updates an existing file, otherwise overwrite
any existing one; optional defaults to false.
doUpdate = c;
savedDoUpdate = c;
| public void | setWhenempty(org.apache.tools.ant.taskdefs.Zip$WhenEmpty we)Sets behavior of the task when no files match.
Possible values are: fail (throw an exception
and halt the build); skip (do not create
any archive, but issue a warning); create
(make an archive with no entries).
Default for zip tasks is skip ;
for jar tasks, create .
emptyBehavior = we.getValue();
| public void | setZipfile(java.io.File zipFile)This is the name/location of where to
create the .zip file.
setDestFile(zipFile);
| protected void | zipDir(java.io.File dir, org.apache.tools.zip.ZipOutputStream zOut, java.lang.String vPath, int mode)Add a directory to the zip stream.
zipDir(dir, zOut, vPath, mode, null);
| protected void | zipDir(java.io.File dir, org.apache.tools.zip.ZipOutputStream zOut, java.lang.String vPath, int mode, org.apache.tools.zip.ZipExtraField[] extra)Add a directory to the zip stream.
if (doFilesonly) {
log("skipping directory " + vPath + " for file-only archive",
Project.MSG_VERBOSE);
return;
}
if (addedDirs.get(vPath) != null) {
// don't add directories we've already added.
// no warning if we try, it is harmless in and of itself
return;
}
log("adding directory " + vPath, Project.MSG_VERBOSE);
addedDirs.put(vPath, vPath);
if (!skipWriting) {
ZipEntry ze = new ZipEntry (vPath);
if (dir != null && dir.exists()) {
// ZIPs store time with a granularity of 2 seconds, round up
ze.setTime(dir.lastModified() + (roundUp ? 1999 : 0));
} else {
// ZIPs store time with a granularity of 2 seconds, round up
ze.setTime(System.currentTimeMillis() + (roundUp ? 1999 : 0));
}
ze.setSize (0);
ze.setMethod (ZipEntry.STORED);
// This is faintly ridiculous:
ze.setCrc (EMPTY_CRC);
ze.setUnixMode(mode);
if (extra != null) {
ze.setExtraFields(extra);
}
zOut.putNextEntry(ze);
}
| protected void | zipFile(java.io.InputStream in, org.apache.tools.zip.ZipOutputStream zOut, java.lang.String vPath, long lastModified, java.io.File fromArchive, int mode)Adds a new entry to the archive, takes care of duplicates as well.
if (entries.contains(vPath)) {
if (duplicate.equals("preserve")) {
log(vPath + " already added, skipping", Project.MSG_INFO);
return;
} else if (duplicate.equals("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);
}
} else {
log("adding entry " + vPath, Project.MSG_VERBOSE);
}
entries.put(vPath, vPath);
if (!skipWriting) {
ZipEntry ze = new ZipEntry(vPath);
ze.setTime(lastModified);
ze.setMethod(doCompress ? ZipEntry.DEFLATED : ZipEntry.STORED);
/*
* ZipOutputStream.putNextEntry expects the ZipEntry to
* know its size and the CRC sum before you start writing
* the data when using STORED mode - unless it is seekable.
*
* This forces us to process the data twice.
*/
if (!zOut.isSeekable() && !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();
}
ze.setSize(size);
ze.setCrc(cal.getValue());
}
ze.setUnixMode(mode);
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);
}
addedFiles.addElement(vPath);
| protected void | zipFile(java.io.File file, org.apache.tools.zip.ZipOutputStream zOut, java.lang.String vPath, int mode)Method that gets called when adding from java.io.File instances.
This implementation delegates to the six-arg version.
if (file.equals(zipFile)) {
throw new BuildException("A zip file cannot include itself",
getLocation());
}
FileInputStream fIn = new FileInputStream(file);
try {
// ZIPs store time with a granularity of 2 seconds, round up
zipFile(fIn, zOut, vPath,
file.lastModified() + (roundUp ? 1999 : 0),
null, mode);
} finally {
fIn.close();
}
|
|