--- a/jdk/src/share/classes/sun/tools/jar/Main.java Wed Dec 10 14:03:15 2008 -0800
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java Wed Dec 17 22:50:37 2008 -0800
@@ -46,9 +46,18 @@
String zname = "";
String[] files;
String rootjar = null;
- Hashtable filesTable = new Hashtable();
- Vector paths = new Vector();
- Vector v;
+
+ // An entryName(path)->File map generated during "expand", it helps to
+ // decide whether or not an existing entry in a jar file needs to be
+ // replaced, during the "update" operation.
+ Map<String, File> entryMap = new HashMap<String, File>();
+
+ // All files need to be added/updated.
+ Set<File> entries = new LinkedHashSet<File>();
+
+ // Directories specified by "-C" operation.
+ List<String> paths = new ArrayList<String>();
+
CRC32 crc32 = new CRC32();
/*
* cflag: create
@@ -175,7 +184,8 @@
vflag = false;
}
}
- create(new BufferedOutputStream(out), expand(files), manifest);
+ expand(null, files, false);
+ create(new BufferedOutputStream(out, 4096), manifest);
if (in != null) {
in.close();
}
@@ -198,8 +208,8 @@
}
InputStream manifest = (!Mflag && (mname != null)) ?
(new FileInputStream(mname)) : null;
- expand(files);
- boolean updateOk = update(in, new BufferedOutputStream(out), manifest);
+ expand(null, files, true);
+ boolean updateOk = update(in, new BufferedOutputStream(out), manifest, null);
if (ok) {
ok = updateOk;
}
@@ -354,7 +364,7 @@
while (dir.indexOf("//") > -1) {
dir = dir.replace("//", "/");
}
- paths.addElement(dir.replace(File.separatorChar, '/'));
+ paths.add(dir.replace(File.separatorChar, '/'));
nameBuf[k++] = dir + args[++i];
} else {
nameBuf[k++] = args[i];
@@ -387,17 +397,7 @@
* Expands list of files to process into full list of all files that
* can be found by recursively descending directories.
*/
- String[] expand(String[] files) {
- v = new Vector();
- expand(null, files, v, filesTable);
- files = new String[v.size()];
- for (int i = 0; i < files.length; i++) {
- files[i] = ((File)v.elementAt(i)).getPath();
- }
- return files;
- }
-
- void expand(File dir, String[] files, Vector v, Hashtable t) {
+ void expand(File dir, String[] files, boolean isUpdate) {
if (files == null) {
return;
}
@@ -409,17 +409,20 @@
f = new File(dir, files[i]);
}
if (f.isFile()) {
- if (!t.contains(f)) {
- t.put(entryName(f.getPath()), f);
- v.addElement(f);
+ if (entries.add(f)) {
+ if (isUpdate)
+ entryMap.put(entryName(f.getPath()), f);
}
} else if (f.isDirectory()) {
- String dirPath = f.getPath();
- dirPath = (dirPath.endsWith(File.separator)) ? dirPath :
- (dirPath + File.separator);
- t.put(entryName(dirPath), f);
- v.addElement(f);
- expand(f, f.list(), v, t);
+ if (entries.add(f)) {
+ if (isUpdate) {
+ String dirPath = f.getPath();
+ dirPath = (dirPath.endsWith(File.separator)) ? dirPath :
+ (dirPath + File.separator);
+ entryMap.put(entryName(dirPath), f);
+ }
+ expand(f, f.list(), isUpdate);
+ }
} else {
error(formatMsg("error.nosuch.fileordir", String.valueOf(f)));
ok = false;
@@ -430,7 +433,7 @@
/*
* Creates a new JAR file.
*/
- void create(OutputStream out, String[] files, Manifest manifest)
+ void create(OutputStream out, Manifest manifest)
throws IOException
{
ZipOutputStream zos = new JarOutputStream(out);
@@ -455,8 +458,8 @@
manifest.write(zos);
zos.closeEntry();
}
- for (int i = 0; i < files.length; i++) {
- addFile(zos, new File(files[i]));
+ for (File file: entries) {
+ addFile(zos, file);
}
zos.close();
}
@@ -465,10 +468,9 @@
* update an existing jar file.
*/
boolean update(InputStream in, OutputStream out,
- InputStream newManifest) throws IOException
+ InputStream newManifest,
+ JarIndex jarIndex) throws IOException
{
- Hashtable t = filesTable;
- Vector v = this.v;
ZipInputStream zis = new ZipInputStream(in);
ZipOutputStream zos = new JarOutputStream(out);
ZipEntry e = null;
@@ -477,8 +479,8 @@
int n = 0;
boolean updateOk = true;
- if (t.containsKey(INDEX)) {
- addIndex((JarIndex)t.get(INDEX), zos);
+ if (jarIndex != null) {
+ addIndex(jarIndex, zos);
}
// put the old entries first, replace if necessary
@@ -488,9 +490,8 @@
boolean isManifestEntry = name.toUpperCase(
java.util.Locale.ENGLISH).
equals(MANIFEST);
- if ((name.toUpperCase().equals(INDEX)
- && t.containsKey(INDEX))
- || (Mflag && isManifestEntry)) {
+ if ((name.toUpperCase().equals(INDEX) && jarIndex != null)
+ || (Mflag && isManifestEntry)) {
continue;
} else if (isManifestEntry && ((newManifest != null) ||
(ename != null))) {
@@ -514,8 +515,7 @@
}
updateManifest(old, zos);
} else {
- if (!t.containsKey(name)) { // copy the old stuff
-
+ if (!entryMap.containsKey(name)) { // copy the old stuff
// do our own compression
ZipEntry e2 = new ZipEntry(name);
e2.setMethod(e.getMethod());
@@ -531,21 +531,17 @@
zos.write(buf, 0, n);
}
} else { // replace with the new files
- addFile(zos, (File)(t.get(name)));
- t.remove(name);
+ File f = entryMap.get(name);
+ addFile(zos, f);
+ entryMap.remove(name);
+ entries.remove(f);
}
}
}
- t.remove(INDEX);
// add the remaining new files
- if (!t.isEmpty()) {
- for (int i = 0; i < v.size(); i++) {
- File f = (File)v.elementAt(i);
- if (t.containsValue(f)) {
- addFile(zos, f);
- }
- }
+ for (File f: entries) {
+ addFile(zos, f);
}
if (!foundManifest) {
if (newManifest != null) {
@@ -611,8 +607,7 @@
private String entryName(String name) {
name = name.replace(File.separatorChar, '/');
String matchPath = "";
- for (int i = 0; i < paths.size(); i++) {
- String path = (String)paths.elementAt(i);
+ for (String path : paths) {
if (name.startsWith(path) && (path.length() > matchPath.length())) {
matchPath = path;
}
@@ -669,7 +664,6 @@
void addFile(ZipOutputStream zos, File file) throws IOException {
String name = file.getPath();
boolean isDir = file.isDirectory();
-
if (isDir) {
name = name.endsWith(File.separator) ? name :
(name + File.separator);
@@ -704,7 +698,7 @@
}
zos.putNextEntry(e);
if (!isDir) {
- byte[] buf = new byte[1024];
+ byte[] buf = new byte[8192];
int len;
InputStream is = new BufferedInputStream(new FileInputStream(file));
while ((len = is.read(buf, 0, buf.length)) != -1) {
@@ -749,7 +743,7 @@
*/
private void crc32File(ZipEntry e, File f) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(f));
- byte[] buf = new byte[1024];
+ byte[] buf = new byte[8192];
crc32.reset();
int r = 0;
int nread = 0;
@@ -772,7 +766,7 @@
void extract(InputStream in, String files[]) throws IOException {
ZipInputStream zis = new ZipInputStream(in);
ZipEntry e;
- // Set of all directory entries specified in archive. Dissallows
+ // Set of all directory entries specified in archive. Disallows
// null entries. Disallows all entries if using pre-6.0 behavior.
Set<ZipEntry> dirs = new HashSet<ZipEntry>() {
public boolean add(ZipEntry e) {
@@ -897,17 +891,16 @@
}
}
-
/**
* Output the class index table to the INDEX.LIST file of the
* root jar file.
*/
void dumpIndex(String rootjar, JarIndex index) throws IOException {
- filesTable.put(INDEX, index);
File scratchFile = File.createTempFile("scratch", null, new File("."));
File jarFile = new File(rootjar);
boolean updateOk = update(new FileInputStream(jarFile),
- new FileOutputStream(scratchFile), null);
+ new FileOutputStream(scratchFile),
+ null, index);
jarFile.delete();
if (!scratchFile.renameTo(jarFile)) {
scratchFile.delete();