This happens mainly for two reasons: * preserve stored permissions unless the user explicitly overrides them (PR 2130). This is now fixed for stored files, but not for directories. * deal with filename encoding of existing archives. Supposed to work properly now. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274751 13f79535-47bb-0310-9956-ffa450edef68master
@@ -66,7 +66,6 @@ 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 org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
@@ -85,6 +84,7 @@ import org.apache.tools.ant.util.IdentityMapper; | |||||
import org.apache.tools.ant.util.MergingMapper; | import org.apache.tools.ant.util.MergingMapper; | ||||
import org.apache.tools.ant.util.ResourceUtils; | import org.apache.tools.ant.util.ResourceUtils; | ||||
import org.apache.tools.zip.ZipEntry; | import org.apache.tools.zip.ZipEntry; | ||||
import org.apache.tools.zip.ZipFile; | |||||
import org.apache.tools.zip.ZipOutputStream; | import org.apache.tools.zip.ZipOutputStream; | ||||
/** | /** | ||||
@@ -362,6 +362,7 @@ public class Zip extends MatchingTask { | |||||
log("Adding file " + files[j] + " to fileset", | log("Adding file " + files[j] + " to fileset", | ||||
Project.MSG_VERBOSE); | Project.MSG_VERBOSE); | ||||
ZipFileSet zf = new ZipFileSet(); | ZipFileSet zf = new ZipFileSet(); | ||||
zf.setProject(getProject()); | |||||
zf.setSrc(new File(basedir, files[j])); | zf.setSrc(new File(basedir, files[j])); | ||||
filesets.addElement(zf); | filesets.addElement(zf); | ||||
filesetsFromGroupfilesets.addElement(zf); | filesetsFromGroupfilesets.addElement(zf); | ||||
@@ -439,6 +440,7 @@ public class Zip extends MatchingTask { | |||||
if (doUpdate) { | if (doUpdate) { | ||||
addingNewFiles = false; | addingNewFiles = false; | ||||
ZipFileSet oldFiles = new ZipFileSet(); | ZipFileSet oldFiles = new ZipFileSet(); | ||||
oldFiles.setProject(getProject()); | |||||
oldFiles.setSrc(renamedFile); | oldFiles.setSrc(renamedFile); | ||||
for (int i = 0; i < addedFiles.size(); i++) { | for (int i = 0; i < addedFiles.size(); i++) { | ||||
@@ -447,6 +449,7 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
DirectoryScanner ds = | DirectoryScanner ds = | ||||
oldFiles.getDirectoryScanner(getProject()); | oldFiles.getDirectoryScanner(getProject()); | ||||
((ZipScanner) ds).setEncoding(encoding); | |||||
String[] f = ds.getIncludedFiles(); | String[] f = ds.getIncludedFiles(); | ||||
Resource[] r = new Resource[f.length]; | Resource[] r = new Resource[f.length]; | ||||
for (int i = 0; i < f.length; i++) { | for (int i = 0; i < f.length; i++) { | ||||
@@ -575,7 +578,7 @@ public class Zip extends MatchingTask { | |||||
dealingWithFiles = true; | dealingWithFiles = true; | ||||
base = fileset.getDir(getProject()); | base = fileset.getDir(getProject()); | ||||
} else { | } else { | ||||
zf = new ZipFile(zfs.getSrc(getProject())); | |||||
zf = new ZipFile(zfs.getSrc(getProject()), encoding); | |||||
} | } | ||||
for (int i = 0; i < resources.length; i++) { | for (int i = 0; i < resources.length; i++) { | ||||
@@ -595,17 +598,18 @@ public class Zip extends MatchingTask { | |||||
} | } | ||||
addParentDirs(base, name, zOut, prefix, dirMode); | addParentDirs(base, name, zOut, prefix, dirMode); | ||||
if (!resources[i].isDirectory() && dealingWithFiles) { | if (!resources[i].isDirectory() && dealingWithFiles) { | ||||
File f = fileUtils.resolveFile(base, | File f = fileUtils.resolveFile(base, | ||||
resources[i].getName()); | resources[i].getName()); | ||||
zipFile(f, zOut, prefix + name, fileMode); | zipFile(f, zOut, prefix + name, fileMode); | ||||
} else if (!resources[i].isDirectory()) { | } else if (!resources[i].isDirectory()) { | ||||
java.util.zip.ZipEntry ze = | |||||
zf.getEntry(resources[i].getName()); | |||||
ZipEntry ze = zf.getEntry(resources[i].getName()); | |||||
if (ze != null) { | if (ze != null) { | ||||
zipFile(zf.getInputStream(ze), zOut, prefix + name, | zipFile(zf.getInputStream(ze), zOut, prefix + name, | ||||
ze.getTime(), zfs.getSrc(getProject()), fileMode); | |||||
ze.getTime(), zfs.getSrc(getProject()), | |||||
zfs.hasFileModeBeenSet() ? fileMode | |||||
: ze.getUnixMode()); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -673,6 +677,7 @@ public class Zip extends MatchingTask { | |||||
private synchronized ZipScanner getZipScanner() { | private synchronized ZipScanner getZipScanner() { | ||||
if (zs == null) { | if (zs == null) { | ||||
zs = new ZipScanner(); | zs = new ZipScanner(); | ||||
zs.setEncoding(encoding); | |||||
zs.setSrc(zipFile); | zs.setSrc(zipFile); | ||||
} | } | ||||
return zs; | return zs; | ||||
@@ -849,6 +854,9 @@ public class Zip extends MatchingTask { | |||||
for (int i = 0; i < filesets.length; i++) { | for (int i = 0; i < filesets.length; i++) { | ||||
DirectoryScanner rs = | DirectoryScanner rs = | ||||
filesets[i].getDirectoryScanner(getProject()); | filesets[i].getDirectoryScanner(getProject()); | ||||
if (rs instanceof ZipScanner) { | |||||
((ZipScanner) rs).setEncoding(encoding); | |||||
} | |||||
Vector resources = new Vector(); | Vector resources = new Vector(); | ||||
String[] directories = rs.getIncludedDirectories(); | String[] directories = rs.getIncludedDirectories(); | ||||
for (int j = 0; j < directories.length; j++) { | for (int j = 0; j < directories.length; j++) { | ||||
@@ -98,6 +98,9 @@ public class ZipFileSet extends FileSet { | |||||
private int fileMode = DEFAULT_FILE_MODE; | private int fileMode = DEFAULT_FILE_MODE; | ||||
private int dirMode = DEFAULT_DIR_MODE; | private int dirMode = DEFAULT_DIR_MODE; | ||||
private boolean fileModeHasBeenSet = false; | |||||
private boolean dirModeHasBeenSet = false; | |||||
public ZipFileSet() { | public ZipFileSet() { | ||||
super(); | super(); | ||||
} | } | ||||
@@ -114,6 +117,8 @@ public class ZipFileSet extends FileSet { | |||||
hasDir = fileset.hasDir; | hasDir = fileset.hasDir; | ||||
fileMode = fileset.fileMode; | fileMode = fileset.fileMode; | ||||
dirMode = fileset.dirMode; | dirMode = fileset.dirMode; | ||||
fileModeHasBeenSet = fileset.fileModeHasBeenSet; | |||||
dirModeHasBeenSet = fileset.dirModeHasBeenSet; | |||||
} | } | ||||
/** | /** | ||||
@@ -243,7 +248,8 @@ public class ZipFileSet extends FileSet { | |||||
public void setFileMode(String octalString) { | public void setFileMode(String octalString) { | ||||
if (isReference()) { | if (isReference()) { | ||||
throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
} | |||||
} | |||||
fileModeHasBeenSet = true; | |||||
this.fileMode = | this.fileMode = | ||||
UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8); | UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8); | ||||
} | } | ||||
@@ -258,23 +264,36 @@ public class ZipFileSet extends FileSet { | |||||
return fileMode; | return fileMode; | ||||
} | } | ||||
/** | |||||
* Whether the user has specified the mode explicitly. | |||||
* | |||||
* @since Ant 1.6 | |||||
*/ | |||||
public boolean hasFileModeBeenSet() { | |||||
if (isReference()) { | |||||
return ((ZipFileSet)getRef(getProject())).hasFileModeBeenSet(); | |||||
} | |||||
return fileModeHasBeenSet; | |||||
} | |||||
/** | /** | ||||
* A 3 digit octal string, specify the user, group and | * A 3 digit octal string, specify the user, group and | ||||
* other modes in the standard Unix fashion; | * other modes in the standard Unix fashion; | ||||
* optional, default=0755 | * optional, default=0755 | ||||
* | * | ||||
* @since Ant 1.6 | |||||
* @since Ant 1.5.2 | |||||
*/ | */ | ||||
public void setDirMode(String octalString) { | public void setDirMode(String octalString) { | ||||
if (isReference()) { | if (isReference()) { | ||||
throw tooManyAttributes(); | throw tooManyAttributes(); | ||||
} | |||||
} | |||||
dirModeHasBeenSet = true; | |||||
this.dirMode = | this.dirMode = | ||||
UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8); | UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8); | ||||
} | } | ||||
/** | /** | ||||
* @since Ant 1.6 | |||||
* @since Ant 1.5.2 | |||||
*/ | */ | ||||
public int getDirMode(Project p) { | public int getDirMode(Project p) { | ||||
if (isReference()) { | if (isReference()) { | ||||
@@ -283,6 +302,18 @@ public class ZipFileSet extends FileSet { | |||||
return dirMode; | return dirMode; | ||||
} | } | ||||
/** | |||||
* Whether the user has specified the mode explicitly. | |||||
* | |||||
* @since Ant 1.6 | |||||
*/ | |||||
public boolean hasDirModeBeenSet() { | |||||
if (isReference()) { | |||||
return ((ZipFileSet)getRef(getProject())).hasDirModeBeenSet(); | |||||
} | |||||
return dirModeHasBeenSet; | |||||
} | |||||
/** | /** | ||||
* A ZipFileset accepts another ZipFileSet or a FileSet as reference | * A ZipFileset accepts another ZipFileSet or a FileSet as reference | ||||
* FileSets are often used by the war task for the lib attribute | * FileSets are often used by the war task for the lib attribute | ||||
@@ -60,12 +60,12 @@ import java.io.IOException; | |||||
import java.util.Vector; | import java.util.Vector; | ||||
import java.util.Hashtable; | import java.util.Hashtable; | ||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.zip.ZipInputStream; | |||||
import java.util.zip.ZipEntry; | |||||
import java.util.zip.ZipException; | import java.util.zip.ZipException; | ||||
import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
import org.apache.tools.zip.ZipEntry; | |||||
import org.apache.tools.zip.ZipFile; | |||||
/** | /** | ||||
* ZipScanner accesses the pattern matching algorithm in DirectoryScanner, | * ZipScanner accesses the pattern matching algorithm in DirectoryScanner, | ||||
@@ -92,6 +92,13 @@ public class ZipScanner extends DirectoryScanner { | |||||
*/ | */ | ||||
private Hashtable myentries; | private Hashtable myentries; | ||||
/** | |||||
* encoding of file names. | |||||
* | |||||
* @since Ant 1.6 | |||||
*/ | |||||
private String encoding; | |||||
/** | /** | ||||
* Sets the srcFile for scanning. This is the jar or zip file that | * Sets the srcFile for scanning. This is the jar or zip file that | ||||
* is scanned for matching entries. | * is scanned for matching entries. | ||||
@@ -102,6 +109,15 @@ public class ZipScanner extends DirectoryScanner { | |||||
this.srcFile = srcFile; | this.srcFile = srcFile; | ||||
} | } | ||||
/** | |||||
* Sets encoding of file names. | |||||
* | |||||
* @since Ant 1.6 | |||||
*/ | |||||
public void setEncoding(String encoding) { | |||||
this.encoding = encoding; | |||||
} | |||||
/** | /** | ||||
* Returns the names of the files which matched at least one of the | * Returns the names of the files which matched at least one of the | ||||
* include patterns and none of the exclude patterns. | * include patterns and none of the exclude patterns. | ||||
@@ -230,37 +246,29 @@ public class ZipScanner extends DirectoryScanner { | |||||
} | } | ||||
ZipEntry entry = null; | ZipEntry entry = null; | ||||
ZipInputStream in = null; | |||||
ZipFile zf = null; | |||||
myentries = new Hashtable(); | myentries = new Hashtable(); | ||||
try { | try { | ||||
try { | try { | ||||
in = new ZipInputStream(new FileInputStream(srcFile)); | |||||
zf = new ZipFile(srcFile, encoding); | |||||
} catch (ZipException ex) { | |||||
throw new BuildException("problem reading " + srcFile, ex); | |||||
} catch (IOException ex) { | } catch (IOException ex) { | ||||
throw new BuildException("problem opening " + srcFile, ex); | throw new BuildException("problem opening " + srcFile, ex); | ||||
} | } | ||||
while (true) { | |||||
try { | |||||
entry = in.getNextEntry(); | |||||
if (entry == null) { | |||||
break; | |||||
} | |||||
myentries.put(new String(entry.getName()), | |||||
new Resource(entry.getName(), true, | |||||
entry.getTime(), | |||||
entry.isDirectory())); | |||||
} catch (ZipException ex) { | |||||
throw new BuildException("problem reading " + srcFile, | |||||
ex); | |||||
} catch (IOException e) { | |||||
throw new BuildException("problem reading zip entry from " | |||||
+ srcFile, e); | |||||
} | |||||
Enumeration enum = zf.getEntries(); | |||||
while (enum.hasMoreElements()) { | |||||
entry = (ZipEntry) enum.nextElement(); | |||||
myentries.put(new String(entry.getName()), | |||||
new Resource(entry.getName(), true, | |||||
entry.getTime(), | |||||
entry.isDirectory())); | |||||
} | } | ||||
} finally { | } finally { | ||||
if (in != null) { | |||||
if (zf != null) { | |||||
try { | try { | ||||
in.close(); | |||||
zf.close(); | |||||
} catch (IOException ex) { | } catch (IOException ex) { | ||||
// swallow | // swallow | ||||
} | } | ||||