You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2013/05/25 19:47:00 UTC
svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Author: bodewig
Date: Sat May 25 17:47:00 2013
New Revision: 1486348
URL: http://svn.apache.org/r1486348
Log:
provide access to all entries of a given name in ZipFile, COMPRESS-227
Modified:
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Sat May 25 17:47:00 2013
@@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
@@ -83,17 +86,17 @@ public class ZipFile {
private static final int POS_3 = 3;
/**
- * Maps ZipArchiveEntrys to two longs, recording the offsets of
- * the local file headers and the start of entry data.
+ * List of entries in the order they appear inside the central
+ * directory.
*/
- private final Map<ZipArchiveEntry, OffsetEntry> entries =
- new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
+ private final List<ZipArchiveEntry> entries =
+ new LinkedList<ZipArchiveEntry>();
/**
- * Maps String to ZipArchiveEntrys, name -> actual entry.
+ * Maps String to list of ZipArchiveEntrys, name -> actual entries.
*/
- private final Map<String, ZipArchiveEntry> nameMap =
- new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
+ private final Map<String, Deque<ZipArchiveEntry>> nameMap =
+ new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
private static final class OffsetEntry {
private long headerOffset = -1;
@@ -273,7 +276,7 @@ public class ZipFile {
* @return all entries as {@link ZipArchiveEntry} instances
*/
public Enumeration<ZipArchiveEntry> getEntries() {
- return Collections.enumeration(entries.keySet());
+ return Collections.enumeration(entries);
}
/**
@@ -287,8 +290,7 @@ public class ZipFile {
* @since 1.1
*/
public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
- ZipArchiveEntry[] allEntries =
- entries.keySet().toArray(new ZipArchiveEntry[0]);
+ ZipArchiveEntry[] allEntries = entries.toArray(new ZipArchiveEntry[0]);
Arrays.sort(allEntries, OFFSET_COMPARATOR);
return Collections.enumeration(Arrays.asList(allEntries));
}
@@ -296,12 +298,51 @@ public class ZipFile {
/**
* Returns a named entry - or {@code null} if no entry by
* that name exists.
+ *
+ * <p>If multiple entries with the same name exist the first entry
+ * in the archive's central directory by that name is
+ * returned.</p>
+ *
* @param name name of the entry.
* @return the ZipArchiveEntry corresponding to the given name - or
* {@code null} if not present.
*/
public ZipArchiveEntry getEntry(String name) {
- return nameMap.get(name);
+ Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
+ return entriesOfThatName != null ? entriesOfThatName.getFirst() : null;
+ }
+
+ /**
+ * Returns all named entries in the same order they appear within
+ * the archive's central directory.
+ *
+ * @param name name of the entry.
+ * @return the Iterator<ZipArchiveEntry> corresponding to the
+ * given name
+ * @since 1.6
+ */
+ public Iterator<ZipArchiveEntry> getEntries(String name) {
+ Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
+ return entriesOfThatName != null ? entriesOfThatName.iterator()
+ : Collections.<ZipArchiveEntry>emptyList().iterator();
+ }
+
+ /**
+ * Returns all named entries in the same order their contents
+ * appear within the archive.
+ *
+ * @param name name of the entry.
+ * @return the Iterator<ZipArchiveEntry> corresponding to the
+ * given name
+ * @since 1.6
+ */
+ public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String name) {
+ ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
+ if (nameMap.containsKey(name)) {
+ entriesOfThatName = nameMap.get(name).toArray(entriesOfThatName);
+ Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
+ }
+ return Arrays.asList(entriesOfThatName).iterator();
}
/**
@@ -325,10 +366,12 @@ public class ZipFile {
*/
public InputStream getInputStream(ZipArchiveEntry ze)
throws IOException, ZipException {
- OffsetEntry offsetEntry = entries.get(ze);
- if (offsetEntry == null) {
+ if (!(ze instanceof Entry)) {
return null;
}
+ // checked just above
+ @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
+ ((Entry) ze).getOffsetEntry();
ZipUtil.checkRequestedFeatures(ze);
long start = offsetEntry.dataOffset;
BoundedInputStream bis =
@@ -474,7 +517,8 @@ public class ZipFile {
throws IOException {
archive.readFully(CFH_BUF);
int off = 0;
- ZipArchiveEntry ze = new ZipArchiveEntry();
+ OffsetEntry offset = new OffsetEntry();
+ Entry ze = new Entry(offset);
int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
off += SHORT;
@@ -529,10 +573,9 @@ public class ZipFile {
ze.setName(entryEncoding.decode(fileName), fileName);
// LFH offset,
- OffsetEntry offset = new OffsetEntry();
offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
// data offset will be filled later
- entries.put(ze, offset);
+ entries.add(ze);
byte[] cdExtraData = new byte[extraLen];
archive.readFully(cdExtraData);
@@ -851,16 +894,11 @@ public class ZipFile {
private void resolveLocalFileHeaderData(Map<ZipArchiveEntry, NameAndComment>
entriesWithoutUTF8Flag)
throws IOException {
- // changing the name of a ZipArchiveEntry is going to change
- // the hashcode - see COMPRESS-164
- // Map needs to be reconstructed in order to keep central
- // directory order
- Map<ZipArchiveEntry, OffsetEntry> origMap =
- new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
- entries.clear();
- for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent : origMap.entrySet()) {
- ZipArchiveEntry ze = ent.getKey();
- OffsetEntry offsetEntry = ent.getValue();
+ for (Iterator<ZipArchiveEntry> it = entries.iterator(); it.hasNext(); ) {
+ // entries is filled in populateFromCentralDirectory and
+ // never modified
+ @SuppressWarnings("unchecked") Entry ze = (Entry) it.next();
+ OffsetEntry offsetEntry = ze.getOffsetEntry();
long offset = offsetEntry.headerOffset;
archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
archive.readFully(SHORT_BUF);
@@ -883,13 +921,18 @@ public class ZipFile {
+ SHORT + SHORT + fileNameLen + extraFieldLen;
if (entriesWithoutUTF8Flag.containsKey(ze)) {
- String orig = ze.getName();
NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
nc.comment);
}
- entries.put(ze, offsetEntry);
- nameMap.put(ze.getName(), ze);
+
+ String name = ze.getName();
+ Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
+ if (entriesOfThatName == null) {
+ entriesOfThatName = new LinkedList<ZipArchiveEntry>();
+ nameMap.put(name, entriesOfThatName);
+ }
+ entriesOfThatName.addLast(ze);
}
}
@@ -996,16 +1039,54 @@ public class ZipFile {
return 0;
}
- OffsetEntry off1 = entries.get(e1);
- OffsetEntry off2 = entries.get(e2);
- if (off1 == null) {
+ @SuppressWarnings("unchecked") Entry ent1 =
+ e1 instanceof Entry ? (Entry) e1 : null;
+ @SuppressWarnings("unchecked") Entry ent2 =
+ e2 instanceof Entry ? (Entry) e2 : null;
+ if (ent1 == null) {
return 1;
}
- if (off2 == null) {
+ if (ent2 == null) {
return -1;
}
- long val = (off1.headerOffset - off2.headerOffset);
+ long val = (ent1.getOffsetEntry().headerOffset
+ - ent2.getOffsetEntry().headerOffset);
return val == 0 ? 0 : val < 0 ? -1 : +1;
}
};
+
+ /**
+ * Extends ZipArchiveEntry to store the offset within the archive.
+ */
+ private static class Entry extends ZipArchiveEntry {
+
+ private final OffsetEntry offsetEntry;
+
+ Entry(OffsetEntry offset) {
+ this.offsetEntry = offset;
+ }
+
+ OffsetEntry getOffsetEntry() {
+ return offsetEntry;
+ }
+
+ @Override
+ public int hashCode() {
+ return 3 * super.hashCode()
+ + (int) (offsetEntry.headerOffset % Integer.MAX_VALUE);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (super.equals(other)) {
+ // super.equals would return false otherwise
+ @SuppressWarnings("unchecked") Entry otherEntry = (Entry) other;
+ return offsetEntry.headerOffset
+ == otherEntry.offsetEntry.headerOffset
+ && offsetEntry.dataOffset
+ == otherEntry.offsetEntry.dataOffset;
+ }
+ return false;
+ }
+ }
}
Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java Sat May 25 17:47:00 2013
@@ -27,6 +27,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.TreeMap;
import java.util.zip.ZipEntry;
@@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
ZipArchiveEntry ze = zf.getEntry("test1.txt");
assertNotNull(ze);
assertNotNull(zf.getInputStream(ze));
+
+ int numberOfEntries = 0;
+ for (Iterator it = zf.getEntries("test1.txt"); it.hasNext(); it.next()) {
+ numberOfEntries++;
+ }
+ assertEquals(2, numberOfEntries);
}
/*
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by Oliver Kopp <ko...@gmail.com>.
Hi,
Gary wrote:
> I'd rather see developers getting and staying involved than clamping new
> versions down with old EOL'd JREs.
According to http://www.oracle.com/technetwork/java/eol-135779.html,
Java 6 already had its EOL on Feb 2013.
Java 7 will have its EOL on March 2015 :).
Debian stable supports JRE 6 and 7 "on most archs"; Google App Engine
also supports Java 6 and 7.
Cheers,
Oliver
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by sebb <se...@gmail.com>.
On 28 May 2013 19:28, Gary Gregory <ga...@gmail.com> wrote:
> On Tue, May 28, 2013 at 2:22 PM, sebb <se...@gmail.com> wrote:
>
>> On 28 May 2013 19:15, Gary Gregory <ga...@gmail.com> wrote:
>> > On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
>> >
>> >> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>> >> > Author: bodewig
>> >> > Date: Sat May 25 17:47:00 2013
>> >> > New Revision: 1486348
>> >> >
>> >> > URL: http://svn.apache.org/r1486348
>> >> > Log:
>> >> > provide access to all entries of a given name in ZipFile, COMPRESS-227
>> >>
>> >> -1, see below
>> >>
>> >> > Modified:
>> >> >
>> >>
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> >> >
>> >>
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> >> >
>> >> > Modified:
>> >>
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> >> > URL:
>> >>
>> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
>> >> >
>> >>
>> ==============================================================================
>> >> > ---
>> >>
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> >> (original)
>> >> > +++
>> >>
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> >> Sat May 25 17:47:00 2013
>> >> > @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
>> >> > import java.util.Arrays;
>> >> > import java.util.Collections;
>> >> > import java.util.Comparator;
>> >> > +import java.util.Deque;
>> >>
>> >> That requires Java 1.6; Compress currently targets 1.5
>> >>
>> >
>> > Well, let's change the requirement to Java 6 for Compress 1.6.
>>
>> That is not something to be done without considering the effect on
>> downstream users.
>>
>
> Sure, but it's the same argument as always: no one forces users to update
> from one version to another. It's a choice. For transitive dependencies,
> you still have to choose to update /something/.
>
> I'd rather see developers getting and staying involved than clamping new
> versions down with old EOL'd JREs.
And the counter-arguments are the same, otherwise we might as well
update to Java 8 as soon as it is GA.
> Gary
>
>>
>> > Gary
>> >
>> >
>> >>
>> >> > import java.util.Enumeration;
>> >> > import java.util.HashMap;
>> >> > -import java.util.LinkedHashMap;
>> >> > +import java.util.Iterator;
>> >> > +import java.util.LinkedList;
>> >> > +import java.util.List;
>> >> > import java.util.Map;
>> >> > import java.util.zip.Inflater;
>> >> > import java.util.zip.InflaterInputStream;
>> >> > @@ -83,17 +86,17 @@ public class ZipFile {
>> >> > private static final int POS_3 = 3;
>> >> >
>> >> > /**
>> >> > - * Maps ZipArchiveEntrys to two longs, recording the offsets of
>> >> > - * the local file headers and the start of entry data.
>> >> > + * List of entries in the order they appear inside the central
>> >> > + * directory.
>> >> > */
>> >> > - private final Map<ZipArchiveEntry, OffsetEntry> entries =
>> >> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
>> >> > + private final List<ZipArchiveEntry> entries =
>> >> > + new LinkedList<ZipArchiveEntry>();
>> >> >
>> >> > /**
>> >> > - * Maps String to ZipArchiveEntrys, name -> actual entry.
>> >> > + * Maps String to list of ZipArchiveEntrys, name -> actual
>> entries.
>> >> > */
>> >> > - private final Map<String, ZipArchiveEntry> nameMap =
>> >> > - new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
>> >> > + private final Map<String, Deque<ZipArchiveEntry>> nameMap =
>> >> > + new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
>> >> >
>> >> > private static final class OffsetEntry {
>> >> > private long headerOffset = -1;
>> >> > @@ -273,7 +276,7 @@ public class ZipFile {
>> >> > * @return all entries as {@link ZipArchiveEntry} instances
>> >> > */
>> >> > public Enumeration<ZipArchiveEntry> getEntries() {
>> >> > - return Collections.enumeration(entries.keySet());
>> >> > + return Collections.enumeration(entries);
>> >> > }
>> >> >
>> >> > /**
>> >> > @@ -287,8 +290,7 @@ public class ZipFile {
>> >> > * @since 1.1
>> >> > */
>> >> > public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
>> >> > - ZipArchiveEntry[] allEntries =
>> >> > - entries.keySet().toArray(new ZipArchiveEntry[0]);
>> >> > + ZipArchiveEntry[] allEntries = entries.toArray(new
>> >> ZipArchiveEntry[0]);
>> >> > Arrays.sort(allEntries, OFFSET_COMPARATOR);
>> >> > return Collections.enumeration(Arrays.asList(allEntries));
>> >> > }
>> >> > @@ -296,12 +298,51 @@ public class ZipFile {
>> >> > /**
>> >> > * Returns a named entry - or {@code null} if no entry by
>> >> > * that name exists.
>> >> > + *
>> >> > + * <p>If multiple entries with the same name exist the first
>> entry
>> >> > + * in the archive's central directory by that name is
>> >> > + * returned.</p>
>> >> > + *
>> >> > * @param name name of the entry.
>> >> > * @return the ZipArchiveEntry corresponding to the given name -
>> or
>> >> > * {@code null} if not present.
>> >> > */
>> >> > public ZipArchiveEntry getEntry(String name) {
>> >> > - return nameMap.get(name);
>> >> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
>> >> > + return entriesOfThatName != null ?
>> entriesOfThatName.getFirst()
>> >> : null;
>> >> > + }
>> >> > +
>> >> > + /**
>> >> > + * Returns all named entries in the same order they appear within
>> >> > + * the archive's central directory.
>> >> > + *
>> >> > + * @param name name of the entry.
>> >> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
>> >> > + * given name
>> >> > + * @since 1.6
>> >> > + */
>> >> > + public Iterator<ZipArchiveEntry> getEntries(String name) {
>> >> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
>> >> > + return entriesOfThatName != null ?
>> entriesOfThatName.iterator()
>> >> > + : Collections.<ZipArchiveEntry>emptyList().iterator();
>> >> > + }
>> >> > +
>> >> > + /**
>> >> > + * Returns all named entries in the same order their contents
>> >> > + * appear within the archive.
>> >> > + *
>> >> > + * @param name name of the entry.
>> >> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
>> >> > + * given name
>> >> > + * @since 1.6
>> >> > + */
>> >> > + public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String
>> >> name) {
>> >> > + ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
>> >> > + if (nameMap.containsKey(name)) {
>> >> > + entriesOfThatName =
>> >> nameMap.get(name).toArray(entriesOfThatName);
>> >> > + Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
>> >> > + }
>> >> > + return Arrays.asList(entriesOfThatName).iterator();
>> >> > }
>> >> >
>> >> > /**
>> >> > @@ -325,10 +366,12 @@ public class ZipFile {
>> >> > */
>> >> > public InputStream getInputStream(ZipArchiveEntry ze)
>> >> > throws IOException, ZipException {
>> >> > - OffsetEntry offsetEntry = entries.get(ze);
>> >> > - if (offsetEntry == null) {
>> >> > + if (!(ze instanceof Entry)) {
>> >> > return null;
>> >> > }
>> >> > + // checked just above
>> >> > + @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
>> >> > + ((Entry) ze).getOffsetEntry();
>> >> > ZipUtil.checkRequestedFeatures(ze);
>> >> > long start = offsetEntry.dataOffset;
>> >> > BoundedInputStream bis =
>> >> > @@ -474,7 +517,8 @@ public class ZipFile {
>> >> > throws IOException {
>> >> > archive.readFully(CFH_BUF);
>> >> > int off = 0;
>> >> > - ZipArchiveEntry ze = new ZipArchiveEntry();
>> >> > + OffsetEntry offset = new OffsetEntry();
>> >> > + Entry ze = new Entry(offset);
>> >> >
>> >> > int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
>> >> > off += SHORT;
>> >> > @@ -529,10 +573,9 @@ public class ZipFile {
>> >> > ze.setName(entryEncoding.decode(fileName), fileName);
>> >> >
>> >> > // LFH offset,
>> >> > - OffsetEntry offset = new OffsetEntry();
>> >> > offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
>> >> > // data offset will be filled later
>> >> > - entries.put(ze, offset);
>> >> > + entries.add(ze);
>> >> >
>> >> > byte[] cdExtraData = new byte[extraLen];
>> >> > archive.readFully(cdExtraData);
>> >> > @@ -851,16 +894,11 @@ public class ZipFile {
>> >> > private void resolveLocalFileHeaderData(Map<ZipArchiveEntry,
>> >> NameAndComment>
>> >> > entriesWithoutUTF8Flag)
>> >> > throws IOException {
>> >> > - // changing the name of a ZipArchiveEntry is going to change
>> >> > - // the hashcode - see COMPRESS-164
>> >> > - // Map needs to be reconstructed in order to keep central
>> >> > - // directory order
>> >> > - Map<ZipArchiveEntry, OffsetEntry> origMap =
>> >> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
>> >> > - entries.clear();
>> >> > - for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent :
>> >> origMap.entrySet()) {
>> >> > - ZipArchiveEntry ze = ent.getKey();
>> >> > - OffsetEntry offsetEntry = ent.getValue();
>> >> > + for (Iterator<ZipArchiveEntry> it = entries.iterator();
>> >> it.hasNext(); ) {
>> >> > + // entries is filled in populateFromCentralDirectory and
>> >> > + // never modified
>> >> > + @SuppressWarnings("unchecked") Entry ze = (Entry)
>> it.next();
>> >> > + OffsetEntry offsetEntry = ze.getOffsetEntry();
>> >> > long offset = offsetEntry.headerOffset;
>> >> > archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
>> >> > archive.readFully(SHORT_BUF);
>> >> > @@ -883,13 +921,18 @@ public class ZipFile {
>> >> > + SHORT + SHORT + fileNameLen + extraFieldLen;
>> >> >
>> >> > if (entriesWithoutUTF8Flag.containsKey(ze)) {
>> >> > - String orig = ze.getName();
>> >> > NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
>> >> > ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name
>> ,
>> >> > nc.comment);
>> >> > }
>> >> > - entries.put(ze, offsetEntry);
>> >> > - nameMap.put(ze.getName(), ze);
>> >> > +
>> >> > + String name = ze.getName();
>> >> > + Deque<ZipArchiveEntry> entriesOfThatName =
>> >> nameMap.get(name);
>> >> > + if (entriesOfThatName == null) {
>> >> > + entriesOfThatName = new
>> LinkedList<ZipArchiveEntry>();
>> >> > + nameMap.put(name, entriesOfThatName);
>> >> > + }
>> >> > + entriesOfThatName.addLast(ze);
>> >> > }
>> >> > }
>> >> >
>> >> > @@ -996,16 +1039,54 @@ public class ZipFile {
>> >> > return 0;
>> >> > }
>> >> >
>> >> > - OffsetEntry off1 = entries.get(e1);
>> >> > - OffsetEntry off2 = entries.get(e2);
>> >> > - if (off1 == null) {
>> >> > + @SuppressWarnings("unchecked") Entry ent1 =
>> >> > + e1 instanceof Entry ? (Entry) e1 : null;
>> >> > + @SuppressWarnings("unchecked") Entry ent2 =
>> >> > + e2 instanceof Entry ? (Entry) e2 : null;
>> >> > + if (ent1 == null) {
>> >> > return 1;
>> >> > }
>> >> > - if (off2 == null) {
>> >> > + if (ent2 == null) {
>> >> > return -1;
>> >> > }
>> >> > - long val = (off1.headerOffset - off2.headerOffset);
>> >> > + long val = (ent1.getOffsetEntry().headerOffset
>> >> > + - ent2.getOffsetEntry().headerOffset);
>> >> > return val == 0 ? 0 : val < 0 ? -1 : +1;
>> >> > }
>> >> > };
>> >> > +
>> >> > + /**
>> >> > + * Extends ZipArchiveEntry to store the offset within the
>> archive.
>> >> > + */
>> >> > + private static class Entry extends ZipArchiveEntry {
>> >> > +
>> >> > + private final OffsetEntry offsetEntry;
>> >> > +
>> >> > + Entry(OffsetEntry offset) {
>> >> > + this.offsetEntry = offset;
>> >> > + }
>> >> > +
>> >> > + OffsetEntry getOffsetEntry() {
>> >> > + return offsetEntry;
>> >> > + }
>> >> > +
>> >> > + @Override
>> >> > + public int hashCode() {
>> >> > + return 3 * super.hashCode()
>> >> > + + (int) (offsetEntry.headerOffset %
>> Integer.MAX_VALUE);
>> >> > + }
>> >> > +
>> >> > + @Override
>> >> > + public boolean equals(Object other) {
>> >> > + if (super.equals(other)) {
>> >> > + // super.equals would return false otherwise
>> >> > + @SuppressWarnings("unchecked") Entry otherEntry =
>> >> (Entry) other;
>> >> > + return offsetEntry.headerOffset
>> >> > + == otherEntry.offsetEntry.headerOffset
>> >> > + && offsetEntry.dataOffset
>> >> > + == otherEntry.offsetEntry.dataOffset;
>> >> > + }
>> >> > + return false;
>> >> > + }
>> >> > + }
>> >> > }
>> >> >
>> >> > Modified:
>> >>
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> >> > URL:
>> >>
>> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
>> >> >
>> >>
>> ==============================================================================
>> >> > ---
>> >>
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> >> (original)
>> >> > +++
>> >>
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> >> Sat May 25 17:47:00 2013
>> >> > @@ -27,6 +27,7 @@ import java.io.OutputStream;
>> >> > import java.util.ArrayList;
>> >> > import java.util.Collections;
>> >> > import java.util.Enumeration;
>> >> > +import java.util.Iterator;
>> >> > import java.util.TreeMap;
>> >> > import java.util.zip.ZipEntry;
>> >> >
>> >> > @@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
>> >> > ZipArchiveEntry ze = zf.getEntry("test1.txt");
>> >> > assertNotNull(ze);
>> >> > assertNotNull(zf.getInputStream(ze));
>> >> > +
>> >> > + int numberOfEntries = 0;
>> >> > + for (Iterator it = zf.getEntries("test1.txt"); it.hasNext();
>> >> it.next()) {
>> >> > + numberOfEntries++;
>> >> > + }
>> >> > + assertEquals(2, numberOfEntries);
>> >> > }
>> >> >
>> >> > /*
>> >> >
>> >> >
>> >>
>> >> ---------------------------------------------------------------------
>> >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> >> For additional commands, e-mail: dev-help@commons.apache.org
>> >>
>> >>
>> >
>> >
>> > --
>> > E-Mail: garydgregory@gmail.com | ggregory@apache.org
>> > Java Persistence with Hibernate, Second Edition<
>> http://www.manning.com/bauer3/>
>> > JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>> > Spring Batch in Action <http://www.manning.com/templier/>
>> > Blog: http://garygregory.wordpress.com
>> > Home: http://garygregory.com/
>> > Tweet! http://twitter.com/GaryGregory
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition<http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by Gary Gregory <ga...@gmail.com>.
On Tue, May 28, 2013 at 2:22 PM, sebb <se...@gmail.com> wrote:
> On 28 May 2013 19:15, Gary Gregory <ga...@gmail.com> wrote:
> > On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
> >
> >> On 25 May 2013 18:47, <bo...@apache.org> wrote:
> >> > Author: bodewig
> >> > Date: Sat May 25 17:47:00 2013
> >> > New Revision: 1486348
> >> >
> >> > URL: http://svn.apache.org/r1486348
> >> > Log:
> >> > provide access to all entries of a given name in ZipFile, COMPRESS-227
> >>
> >> -1, see below
> >>
> >> > Modified:
> >> >
> >>
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> >> >
> >>
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> >> >
> >> > Modified:
> >>
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> >> > URL:
> >>
> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> >> >
> >>
> ==============================================================================
> >> > ---
> >>
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> >> (original)
> >> > +++
> >>
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> >> Sat May 25 17:47:00 2013
> >> > @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
> >> > import java.util.Arrays;
> >> > import java.util.Collections;
> >> > import java.util.Comparator;
> >> > +import java.util.Deque;
> >>
> >> That requires Java 1.6; Compress currently targets 1.5
> >>
> >
> > Well, let's change the requirement to Java 6 for Compress 1.6.
>
> That is not something to be done without considering the effect on
> downstream users.
>
Sure, but it's the same argument as always: no one forces users to update
from one version to another. It's a choice. For transitive dependencies,
you still have to choose to update /something/.
I'd rather see developers getting and staying involved than clamping new
versions down with old EOL'd JREs.
Gary
>
> > Gary
> >
> >
> >>
> >> > import java.util.Enumeration;
> >> > import java.util.HashMap;
> >> > -import java.util.LinkedHashMap;
> >> > +import java.util.Iterator;
> >> > +import java.util.LinkedList;
> >> > +import java.util.List;
> >> > import java.util.Map;
> >> > import java.util.zip.Inflater;
> >> > import java.util.zip.InflaterInputStream;
> >> > @@ -83,17 +86,17 @@ public class ZipFile {
> >> > private static final int POS_3 = 3;
> >> >
> >> > /**
> >> > - * Maps ZipArchiveEntrys to two longs, recording the offsets of
> >> > - * the local file headers and the start of entry data.
> >> > + * List of entries in the order they appear inside the central
> >> > + * directory.
> >> > */
> >> > - private final Map<ZipArchiveEntry, OffsetEntry> entries =
> >> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
> >> > + private final List<ZipArchiveEntry> entries =
> >> > + new LinkedList<ZipArchiveEntry>();
> >> >
> >> > /**
> >> > - * Maps String to ZipArchiveEntrys, name -> actual entry.
> >> > + * Maps String to list of ZipArchiveEntrys, name -> actual
> entries.
> >> > */
> >> > - private final Map<String, ZipArchiveEntry> nameMap =
> >> > - new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
> >> > + private final Map<String, Deque<ZipArchiveEntry>> nameMap =
> >> > + new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
> >> >
> >> > private static final class OffsetEntry {
> >> > private long headerOffset = -1;
> >> > @@ -273,7 +276,7 @@ public class ZipFile {
> >> > * @return all entries as {@link ZipArchiveEntry} instances
> >> > */
> >> > public Enumeration<ZipArchiveEntry> getEntries() {
> >> > - return Collections.enumeration(entries.keySet());
> >> > + return Collections.enumeration(entries);
> >> > }
> >> >
> >> > /**
> >> > @@ -287,8 +290,7 @@ public class ZipFile {
> >> > * @since 1.1
> >> > */
> >> > public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
> >> > - ZipArchiveEntry[] allEntries =
> >> > - entries.keySet().toArray(new ZipArchiveEntry[0]);
> >> > + ZipArchiveEntry[] allEntries = entries.toArray(new
> >> ZipArchiveEntry[0]);
> >> > Arrays.sort(allEntries, OFFSET_COMPARATOR);
> >> > return Collections.enumeration(Arrays.asList(allEntries));
> >> > }
> >> > @@ -296,12 +298,51 @@ public class ZipFile {
> >> > /**
> >> > * Returns a named entry - or {@code null} if no entry by
> >> > * that name exists.
> >> > + *
> >> > + * <p>If multiple entries with the same name exist the first
> entry
> >> > + * in the archive's central directory by that name is
> >> > + * returned.</p>
> >> > + *
> >> > * @param name name of the entry.
> >> > * @return the ZipArchiveEntry corresponding to the given name -
> or
> >> > * {@code null} if not present.
> >> > */
> >> > public ZipArchiveEntry getEntry(String name) {
> >> > - return nameMap.get(name);
> >> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> >> > + return entriesOfThatName != null ?
> entriesOfThatName.getFirst()
> >> : null;
> >> > + }
> >> > +
> >> > + /**
> >> > + * Returns all named entries in the same order they appear within
> >> > + * the archive's central directory.
> >> > + *
> >> > + * @param name name of the entry.
> >> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
> >> > + * given name
> >> > + * @since 1.6
> >> > + */
> >> > + public Iterator<ZipArchiveEntry> getEntries(String name) {
> >> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> >> > + return entriesOfThatName != null ?
> entriesOfThatName.iterator()
> >> > + : Collections.<ZipArchiveEntry>emptyList().iterator();
> >> > + }
> >> > +
> >> > + /**
> >> > + * Returns all named entries in the same order their contents
> >> > + * appear within the archive.
> >> > + *
> >> > + * @param name name of the entry.
> >> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
> >> > + * given name
> >> > + * @since 1.6
> >> > + */
> >> > + public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String
> >> name) {
> >> > + ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
> >> > + if (nameMap.containsKey(name)) {
> >> > + entriesOfThatName =
> >> nameMap.get(name).toArray(entriesOfThatName);
> >> > + Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
> >> > + }
> >> > + return Arrays.asList(entriesOfThatName).iterator();
> >> > }
> >> >
> >> > /**
> >> > @@ -325,10 +366,12 @@ public class ZipFile {
> >> > */
> >> > public InputStream getInputStream(ZipArchiveEntry ze)
> >> > throws IOException, ZipException {
> >> > - OffsetEntry offsetEntry = entries.get(ze);
> >> > - if (offsetEntry == null) {
> >> > + if (!(ze instanceof Entry)) {
> >> > return null;
> >> > }
> >> > + // checked just above
> >> > + @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
> >> > + ((Entry) ze).getOffsetEntry();
> >> > ZipUtil.checkRequestedFeatures(ze);
> >> > long start = offsetEntry.dataOffset;
> >> > BoundedInputStream bis =
> >> > @@ -474,7 +517,8 @@ public class ZipFile {
> >> > throws IOException {
> >> > archive.readFully(CFH_BUF);
> >> > int off = 0;
> >> > - ZipArchiveEntry ze = new ZipArchiveEntry();
> >> > + OffsetEntry offset = new OffsetEntry();
> >> > + Entry ze = new Entry(offset);
> >> >
> >> > int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
> >> > off += SHORT;
> >> > @@ -529,10 +573,9 @@ public class ZipFile {
> >> > ze.setName(entryEncoding.decode(fileName), fileName);
> >> >
> >> > // LFH offset,
> >> > - OffsetEntry offset = new OffsetEntry();
> >> > offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
> >> > // data offset will be filled later
> >> > - entries.put(ze, offset);
> >> > + entries.add(ze);
> >> >
> >> > byte[] cdExtraData = new byte[extraLen];
> >> > archive.readFully(cdExtraData);
> >> > @@ -851,16 +894,11 @@ public class ZipFile {
> >> > private void resolveLocalFileHeaderData(Map<ZipArchiveEntry,
> >> NameAndComment>
> >> > entriesWithoutUTF8Flag)
> >> > throws IOException {
> >> > - // changing the name of a ZipArchiveEntry is going to change
> >> > - // the hashcode - see COMPRESS-164
> >> > - // Map needs to be reconstructed in order to keep central
> >> > - // directory order
> >> > - Map<ZipArchiveEntry, OffsetEntry> origMap =
> >> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
> >> > - entries.clear();
> >> > - for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent :
> >> origMap.entrySet()) {
> >> > - ZipArchiveEntry ze = ent.getKey();
> >> > - OffsetEntry offsetEntry = ent.getValue();
> >> > + for (Iterator<ZipArchiveEntry> it = entries.iterator();
> >> it.hasNext(); ) {
> >> > + // entries is filled in populateFromCentralDirectory and
> >> > + // never modified
> >> > + @SuppressWarnings("unchecked") Entry ze = (Entry)
> it.next();
> >> > + OffsetEntry offsetEntry = ze.getOffsetEntry();
> >> > long offset = offsetEntry.headerOffset;
> >> > archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
> >> > archive.readFully(SHORT_BUF);
> >> > @@ -883,13 +921,18 @@ public class ZipFile {
> >> > + SHORT + SHORT + fileNameLen + extraFieldLen;
> >> >
> >> > if (entriesWithoutUTF8Flag.containsKey(ze)) {
> >> > - String orig = ze.getName();
> >> > NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
> >> > ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name
> ,
> >> > nc.comment);
> >> > }
> >> > - entries.put(ze, offsetEntry);
> >> > - nameMap.put(ze.getName(), ze);
> >> > +
> >> > + String name = ze.getName();
> >> > + Deque<ZipArchiveEntry> entriesOfThatName =
> >> nameMap.get(name);
> >> > + if (entriesOfThatName == null) {
> >> > + entriesOfThatName = new
> LinkedList<ZipArchiveEntry>();
> >> > + nameMap.put(name, entriesOfThatName);
> >> > + }
> >> > + entriesOfThatName.addLast(ze);
> >> > }
> >> > }
> >> >
> >> > @@ -996,16 +1039,54 @@ public class ZipFile {
> >> > return 0;
> >> > }
> >> >
> >> > - OffsetEntry off1 = entries.get(e1);
> >> > - OffsetEntry off2 = entries.get(e2);
> >> > - if (off1 == null) {
> >> > + @SuppressWarnings("unchecked") Entry ent1 =
> >> > + e1 instanceof Entry ? (Entry) e1 : null;
> >> > + @SuppressWarnings("unchecked") Entry ent2 =
> >> > + e2 instanceof Entry ? (Entry) e2 : null;
> >> > + if (ent1 == null) {
> >> > return 1;
> >> > }
> >> > - if (off2 == null) {
> >> > + if (ent2 == null) {
> >> > return -1;
> >> > }
> >> > - long val = (off1.headerOffset - off2.headerOffset);
> >> > + long val = (ent1.getOffsetEntry().headerOffset
> >> > + - ent2.getOffsetEntry().headerOffset);
> >> > return val == 0 ? 0 : val < 0 ? -1 : +1;
> >> > }
> >> > };
> >> > +
> >> > + /**
> >> > + * Extends ZipArchiveEntry to store the offset within the
> archive.
> >> > + */
> >> > + private static class Entry extends ZipArchiveEntry {
> >> > +
> >> > + private final OffsetEntry offsetEntry;
> >> > +
> >> > + Entry(OffsetEntry offset) {
> >> > + this.offsetEntry = offset;
> >> > + }
> >> > +
> >> > + OffsetEntry getOffsetEntry() {
> >> > + return offsetEntry;
> >> > + }
> >> > +
> >> > + @Override
> >> > + public int hashCode() {
> >> > + return 3 * super.hashCode()
> >> > + + (int) (offsetEntry.headerOffset %
> Integer.MAX_VALUE);
> >> > + }
> >> > +
> >> > + @Override
> >> > + public boolean equals(Object other) {
> >> > + if (super.equals(other)) {
> >> > + // super.equals would return false otherwise
> >> > + @SuppressWarnings("unchecked") Entry otherEntry =
> >> (Entry) other;
> >> > + return offsetEntry.headerOffset
> >> > + == otherEntry.offsetEntry.headerOffset
> >> > + && offsetEntry.dataOffset
> >> > + == otherEntry.offsetEntry.dataOffset;
> >> > + }
> >> > + return false;
> >> > + }
> >> > + }
> >> > }
> >> >
> >> > Modified:
> >>
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> >> > URL:
> >>
> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> >> >
> >>
> ==============================================================================
> >> > ---
> >>
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> >> (original)
> >> > +++
> >>
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> >> Sat May 25 17:47:00 2013
> >> > @@ -27,6 +27,7 @@ import java.io.OutputStream;
> >> > import java.util.ArrayList;
> >> > import java.util.Collections;
> >> > import java.util.Enumeration;
> >> > +import java.util.Iterator;
> >> > import java.util.TreeMap;
> >> > import java.util.zip.ZipEntry;
> >> >
> >> > @@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
> >> > ZipArchiveEntry ze = zf.getEntry("test1.txt");
> >> > assertNotNull(ze);
> >> > assertNotNull(zf.getInputStream(ze));
> >> > +
> >> > + int numberOfEntries = 0;
> >> > + for (Iterator it = zf.getEntries("test1.txt"); it.hasNext();
> >> it.next()) {
> >> > + numberOfEntries++;
> >> > + }
> >> > + assertEquals(2, numberOfEntries);
> >> > }
> >> >
> >> > /*
> >> >
> >> >
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >> For additional commands, e-mail: dev-help@commons.apache.org
> >>
> >>
> >
> >
> > --
> > E-Mail: garydgregory@gmail.com | ggregory@apache.org
> > Java Persistence with Hibernate, Second Edition<
> http://www.manning.com/bauer3/>
> > JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> > Spring Batch in Action <http://www.manning.com/templier/>
> > Blog: http://garygregory.wordpress.com
> > Home: http://garygregory.com/
> > Tweet! http://twitter.com/GaryGregory
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>
--
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by sebb <se...@gmail.com>.
On 28 May 2013 19:15, Gary Gregory <ga...@gmail.com> wrote:
> On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
>
>> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>> > Author: bodewig
>> > Date: Sat May 25 17:47:00 2013
>> > New Revision: 1486348
>> >
>> > URL: http://svn.apache.org/r1486348
>> > Log:
>> > provide access to all entries of a given name in ZipFile, COMPRESS-227
>>
>> -1, see below
>>
>> > Modified:
>> >
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> >
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> >
>> > Modified:
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> > URL:
>> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
>> >
>> ==============================================================================
>> > ---
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> (original)
>> > +++
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> Sat May 25 17:47:00 2013
>> > @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
>> > import java.util.Arrays;
>> > import java.util.Collections;
>> > import java.util.Comparator;
>> > +import java.util.Deque;
>>
>> That requires Java 1.6; Compress currently targets 1.5
>>
>
> Well, let's change the requirement to Java 6 for Compress 1.6.
That is not something to be done without considering the effect on
downstream users.
> Gary
>
>
>>
>> > import java.util.Enumeration;
>> > import java.util.HashMap;
>> > -import java.util.LinkedHashMap;
>> > +import java.util.Iterator;
>> > +import java.util.LinkedList;
>> > +import java.util.List;
>> > import java.util.Map;
>> > import java.util.zip.Inflater;
>> > import java.util.zip.InflaterInputStream;
>> > @@ -83,17 +86,17 @@ public class ZipFile {
>> > private static final int POS_3 = 3;
>> >
>> > /**
>> > - * Maps ZipArchiveEntrys to two longs, recording the offsets of
>> > - * the local file headers and the start of entry data.
>> > + * List of entries in the order they appear inside the central
>> > + * directory.
>> > */
>> > - private final Map<ZipArchiveEntry, OffsetEntry> entries =
>> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
>> > + private final List<ZipArchiveEntry> entries =
>> > + new LinkedList<ZipArchiveEntry>();
>> >
>> > /**
>> > - * Maps String to ZipArchiveEntrys, name -> actual entry.
>> > + * Maps String to list of ZipArchiveEntrys, name -> actual entries.
>> > */
>> > - private final Map<String, ZipArchiveEntry> nameMap =
>> > - new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
>> > + private final Map<String, Deque<ZipArchiveEntry>> nameMap =
>> > + new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
>> >
>> > private static final class OffsetEntry {
>> > private long headerOffset = -1;
>> > @@ -273,7 +276,7 @@ public class ZipFile {
>> > * @return all entries as {@link ZipArchiveEntry} instances
>> > */
>> > public Enumeration<ZipArchiveEntry> getEntries() {
>> > - return Collections.enumeration(entries.keySet());
>> > + return Collections.enumeration(entries);
>> > }
>> >
>> > /**
>> > @@ -287,8 +290,7 @@ public class ZipFile {
>> > * @since 1.1
>> > */
>> > public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
>> > - ZipArchiveEntry[] allEntries =
>> > - entries.keySet().toArray(new ZipArchiveEntry[0]);
>> > + ZipArchiveEntry[] allEntries = entries.toArray(new
>> ZipArchiveEntry[0]);
>> > Arrays.sort(allEntries, OFFSET_COMPARATOR);
>> > return Collections.enumeration(Arrays.asList(allEntries));
>> > }
>> > @@ -296,12 +298,51 @@ public class ZipFile {
>> > /**
>> > * Returns a named entry - or {@code null} if no entry by
>> > * that name exists.
>> > + *
>> > + * <p>If multiple entries with the same name exist the first entry
>> > + * in the archive's central directory by that name is
>> > + * returned.</p>
>> > + *
>> > * @param name name of the entry.
>> > * @return the ZipArchiveEntry corresponding to the given name - or
>> > * {@code null} if not present.
>> > */
>> > public ZipArchiveEntry getEntry(String name) {
>> > - return nameMap.get(name);
>> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
>> > + return entriesOfThatName != null ? entriesOfThatName.getFirst()
>> : null;
>> > + }
>> > +
>> > + /**
>> > + * Returns all named entries in the same order they appear within
>> > + * the archive's central directory.
>> > + *
>> > + * @param name name of the entry.
>> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
>> > + * given name
>> > + * @since 1.6
>> > + */
>> > + public Iterator<ZipArchiveEntry> getEntries(String name) {
>> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
>> > + return entriesOfThatName != null ? entriesOfThatName.iterator()
>> > + : Collections.<ZipArchiveEntry>emptyList().iterator();
>> > + }
>> > +
>> > + /**
>> > + * Returns all named entries in the same order their contents
>> > + * appear within the archive.
>> > + *
>> > + * @param name name of the entry.
>> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
>> > + * given name
>> > + * @since 1.6
>> > + */
>> > + public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String
>> name) {
>> > + ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
>> > + if (nameMap.containsKey(name)) {
>> > + entriesOfThatName =
>> nameMap.get(name).toArray(entriesOfThatName);
>> > + Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
>> > + }
>> > + return Arrays.asList(entriesOfThatName).iterator();
>> > }
>> >
>> > /**
>> > @@ -325,10 +366,12 @@ public class ZipFile {
>> > */
>> > public InputStream getInputStream(ZipArchiveEntry ze)
>> > throws IOException, ZipException {
>> > - OffsetEntry offsetEntry = entries.get(ze);
>> > - if (offsetEntry == null) {
>> > + if (!(ze instanceof Entry)) {
>> > return null;
>> > }
>> > + // checked just above
>> > + @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
>> > + ((Entry) ze).getOffsetEntry();
>> > ZipUtil.checkRequestedFeatures(ze);
>> > long start = offsetEntry.dataOffset;
>> > BoundedInputStream bis =
>> > @@ -474,7 +517,8 @@ public class ZipFile {
>> > throws IOException {
>> > archive.readFully(CFH_BUF);
>> > int off = 0;
>> > - ZipArchiveEntry ze = new ZipArchiveEntry();
>> > + OffsetEntry offset = new OffsetEntry();
>> > + Entry ze = new Entry(offset);
>> >
>> > int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
>> > off += SHORT;
>> > @@ -529,10 +573,9 @@ public class ZipFile {
>> > ze.setName(entryEncoding.decode(fileName), fileName);
>> >
>> > // LFH offset,
>> > - OffsetEntry offset = new OffsetEntry();
>> > offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
>> > // data offset will be filled later
>> > - entries.put(ze, offset);
>> > + entries.add(ze);
>> >
>> > byte[] cdExtraData = new byte[extraLen];
>> > archive.readFully(cdExtraData);
>> > @@ -851,16 +894,11 @@ public class ZipFile {
>> > private void resolveLocalFileHeaderData(Map<ZipArchiveEntry,
>> NameAndComment>
>> > entriesWithoutUTF8Flag)
>> > throws IOException {
>> > - // changing the name of a ZipArchiveEntry is going to change
>> > - // the hashcode - see COMPRESS-164
>> > - // Map needs to be reconstructed in order to keep central
>> > - // directory order
>> > - Map<ZipArchiveEntry, OffsetEntry> origMap =
>> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
>> > - entries.clear();
>> > - for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent :
>> origMap.entrySet()) {
>> > - ZipArchiveEntry ze = ent.getKey();
>> > - OffsetEntry offsetEntry = ent.getValue();
>> > + for (Iterator<ZipArchiveEntry> it = entries.iterator();
>> it.hasNext(); ) {
>> > + // entries is filled in populateFromCentralDirectory and
>> > + // never modified
>> > + @SuppressWarnings("unchecked") Entry ze = (Entry) it.next();
>> > + OffsetEntry offsetEntry = ze.getOffsetEntry();
>> > long offset = offsetEntry.headerOffset;
>> > archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
>> > archive.readFully(SHORT_BUF);
>> > @@ -883,13 +921,18 @@ public class ZipFile {
>> > + SHORT + SHORT + fileNameLen + extraFieldLen;
>> >
>> > if (entriesWithoutUTF8Flag.containsKey(ze)) {
>> > - String orig = ze.getName();
>> > NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
>> > ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
>> > nc.comment);
>> > }
>> > - entries.put(ze, offsetEntry);
>> > - nameMap.put(ze.getName(), ze);
>> > +
>> > + String name = ze.getName();
>> > + Deque<ZipArchiveEntry> entriesOfThatName =
>> nameMap.get(name);
>> > + if (entriesOfThatName == null) {
>> > + entriesOfThatName = new LinkedList<ZipArchiveEntry>();
>> > + nameMap.put(name, entriesOfThatName);
>> > + }
>> > + entriesOfThatName.addLast(ze);
>> > }
>> > }
>> >
>> > @@ -996,16 +1039,54 @@ public class ZipFile {
>> > return 0;
>> > }
>> >
>> > - OffsetEntry off1 = entries.get(e1);
>> > - OffsetEntry off2 = entries.get(e2);
>> > - if (off1 == null) {
>> > + @SuppressWarnings("unchecked") Entry ent1 =
>> > + e1 instanceof Entry ? (Entry) e1 : null;
>> > + @SuppressWarnings("unchecked") Entry ent2 =
>> > + e2 instanceof Entry ? (Entry) e2 : null;
>> > + if (ent1 == null) {
>> > return 1;
>> > }
>> > - if (off2 == null) {
>> > + if (ent2 == null) {
>> > return -1;
>> > }
>> > - long val = (off1.headerOffset - off2.headerOffset);
>> > + long val = (ent1.getOffsetEntry().headerOffset
>> > + - ent2.getOffsetEntry().headerOffset);
>> > return val == 0 ? 0 : val < 0 ? -1 : +1;
>> > }
>> > };
>> > +
>> > + /**
>> > + * Extends ZipArchiveEntry to store the offset within the archive.
>> > + */
>> > + private static class Entry extends ZipArchiveEntry {
>> > +
>> > + private final OffsetEntry offsetEntry;
>> > +
>> > + Entry(OffsetEntry offset) {
>> > + this.offsetEntry = offset;
>> > + }
>> > +
>> > + OffsetEntry getOffsetEntry() {
>> > + return offsetEntry;
>> > + }
>> > +
>> > + @Override
>> > + public int hashCode() {
>> > + return 3 * super.hashCode()
>> > + + (int) (offsetEntry.headerOffset % Integer.MAX_VALUE);
>> > + }
>> > +
>> > + @Override
>> > + public boolean equals(Object other) {
>> > + if (super.equals(other)) {
>> > + // super.equals would return false otherwise
>> > + @SuppressWarnings("unchecked") Entry otherEntry =
>> (Entry) other;
>> > + return offsetEntry.headerOffset
>> > + == otherEntry.offsetEntry.headerOffset
>> > + && offsetEntry.dataOffset
>> > + == otherEntry.offsetEntry.dataOffset;
>> > + }
>> > + return false;
>> > + }
>> > + }
>> > }
>> >
>> > Modified:
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> > URL:
>> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
>> >
>> ==============================================================================
>> > ---
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> (original)
>> > +++
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>> Sat May 25 17:47:00 2013
>> > @@ -27,6 +27,7 @@ import java.io.OutputStream;
>> > import java.util.ArrayList;
>> > import java.util.Collections;
>> > import java.util.Enumeration;
>> > +import java.util.Iterator;
>> > import java.util.TreeMap;
>> > import java.util.zip.ZipEntry;
>> >
>> > @@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
>> > ZipArchiveEntry ze = zf.getEntry("test1.txt");
>> > assertNotNull(ze);
>> > assertNotNull(zf.getInputStream(ze));
>> > +
>> > + int numberOfEntries = 0;
>> > + for (Iterator it = zf.getEntries("test1.txt"); it.hasNext();
>> it.next()) {
>> > + numberOfEntries++;
>> > + }
>> > + assertEquals(2, numberOfEntries);
>> > }
>> >
>> > /*
>> >
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
>
> --
> E-Mail: garydgregory@gmail.com | ggregory@apache.org
> Java Persistence with Hibernate, Second Edition<http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src: main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by Stefan Bodewig <bo...@apache.org>.
On 2013-05-29, sebb wrote:
> On 29 May 2013 05:13, Stefan Bodewig <bo...@apache.org> wrote:
>> On 2013-05-28, Gary Gregory wrote:
>>> On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
>>>> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>>>>>> import java.util.Deque;
>>>> That requires Java 1.6; Compress currently targets 1.5
>>> Well, let's change the requirement to Java 6 for Compress 1.6.
>> Not necessary in this case IMHO. The Deque is never exposed to the user
>> so I can change it to LinkedList (the Deque implementation actually
>> used) without feeling bad.
>> I'll take care of it.
> I already did so, but I used a List.
Yes, saw that. LinkedList#getFirst may be slightly faster than #get(0)
and I expect getEntry() to be involked more often that getEntries() so
it may be useful to explicitly use LinkedList.
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by sebb <se...@gmail.com>.
On 29 May 2013 05:13, Stefan Bodewig <bo...@apache.org> wrote:
> On 2013-05-28, Gary Gregory wrote:
>
>> On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
>
>>> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>
>>>>+ import java.util.Deque;
>
>>> That requires Java 1.6; Compress currently targets 1.5
>
>> Well, let's change the requirement to Java 6 for Compress 1.6.
>
> Not necessary in this case IMHO. The Deque is never exposed to the user
> so I can change it to LinkedList (the Deque implementation actually
> used) without feeling bad.
>
> I'll take care of it.
I already did so, but I used a List.
> Stefan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src: main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by Stefan Bodewig <bo...@apache.org>.
On 2013-05-28, Gary Gregory wrote:
> On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
>> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>>>+ import java.util.Deque;
>> That requires Java 1.6; Compress currently targets 1.5
> Well, let's change the requirement to Java 6 for Compress 1.6.
Not necessary in this case IMHO. The Deque is never exposed to the user
so I can change it to LinkedList (the Deque implementation actually
used) without feeling bad.
I'll take care of it.
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by Gary Gregory <ga...@gmail.com>.
On Tue, May 28, 2013 at 2:08 PM, sebb <se...@gmail.com> wrote:
> On 25 May 2013 18:47, <bo...@apache.org> wrote:
> > Author: bodewig
> > Date: Sat May 25 17:47:00 2013
> > New Revision: 1486348
> >
> > URL: http://svn.apache.org/r1486348
> > Log:
> > provide access to all entries of a given name in ZipFile, COMPRESS-227
>
> -1, see below
>
> > Modified:
> >
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> >
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> >
> > Modified:
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> > URL:
> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> >
> ==============================================================================
> > ---
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> (original)
> > +++
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> Sat May 25 17:47:00 2013
> > @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
> > import java.util.Arrays;
> > import java.util.Collections;
> > import java.util.Comparator;
> > +import java.util.Deque;
>
> That requires Java 1.6; Compress currently targets 1.5
>
Well, let's change the requirement to Java 6 for Compress 1.6.
Gary
>
> > import java.util.Enumeration;
> > import java.util.HashMap;
> > -import java.util.LinkedHashMap;
> > +import java.util.Iterator;
> > +import java.util.LinkedList;
> > +import java.util.List;
> > import java.util.Map;
> > import java.util.zip.Inflater;
> > import java.util.zip.InflaterInputStream;
> > @@ -83,17 +86,17 @@ public class ZipFile {
> > private static final int POS_3 = 3;
> >
> > /**
> > - * Maps ZipArchiveEntrys to two longs, recording the offsets of
> > - * the local file headers and the start of entry data.
> > + * List of entries in the order they appear inside the central
> > + * directory.
> > */
> > - private final Map<ZipArchiveEntry, OffsetEntry> entries =
> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
> > + private final List<ZipArchiveEntry> entries =
> > + new LinkedList<ZipArchiveEntry>();
> >
> > /**
> > - * Maps String to ZipArchiveEntrys, name -> actual entry.
> > + * Maps String to list of ZipArchiveEntrys, name -> actual entries.
> > */
> > - private final Map<String, ZipArchiveEntry> nameMap =
> > - new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
> > + private final Map<String, Deque<ZipArchiveEntry>> nameMap =
> > + new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
> >
> > private static final class OffsetEntry {
> > private long headerOffset = -1;
> > @@ -273,7 +276,7 @@ public class ZipFile {
> > * @return all entries as {@link ZipArchiveEntry} instances
> > */
> > public Enumeration<ZipArchiveEntry> getEntries() {
> > - return Collections.enumeration(entries.keySet());
> > + return Collections.enumeration(entries);
> > }
> >
> > /**
> > @@ -287,8 +290,7 @@ public class ZipFile {
> > * @since 1.1
> > */
> > public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
> > - ZipArchiveEntry[] allEntries =
> > - entries.keySet().toArray(new ZipArchiveEntry[0]);
> > + ZipArchiveEntry[] allEntries = entries.toArray(new
> ZipArchiveEntry[0]);
> > Arrays.sort(allEntries, OFFSET_COMPARATOR);
> > return Collections.enumeration(Arrays.asList(allEntries));
> > }
> > @@ -296,12 +298,51 @@ public class ZipFile {
> > /**
> > * Returns a named entry - or {@code null} if no entry by
> > * that name exists.
> > + *
> > + * <p>If multiple entries with the same name exist the first entry
> > + * in the archive's central directory by that name is
> > + * returned.</p>
> > + *
> > * @param name name of the entry.
> > * @return the ZipArchiveEntry corresponding to the given name - or
> > * {@code null} if not present.
> > */
> > public ZipArchiveEntry getEntry(String name) {
> > - return nameMap.get(name);
> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> > + return entriesOfThatName != null ? entriesOfThatName.getFirst()
> : null;
> > + }
> > +
> > + /**
> > + * Returns all named entries in the same order they appear within
> > + * the archive's central directory.
> > + *
> > + * @param name name of the entry.
> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
> > + * given name
> > + * @since 1.6
> > + */
> > + public Iterator<ZipArchiveEntry> getEntries(String name) {
> > + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> > + return entriesOfThatName != null ? entriesOfThatName.iterator()
> > + : Collections.<ZipArchiveEntry>emptyList().iterator();
> > + }
> > +
> > + /**
> > + * Returns all named entries in the same order their contents
> > + * appear within the archive.
> > + *
> > + * @param name name of the entry.
> > + * @return the Iterator<ZipArchiveEntry> corresponding to the
> > + * given name
> > + * @since 1.6
> > + */
> > + public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String
> name) {
> > + ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
> > + if (nameMap.containsKey(name)) {
> > + entriesOfThatName =
> nameMap.get(name).toArray(entriesOfThatName);
> > + Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
> > + }
> > + return Arrays.asList(entriesOfThatName).iterator();
> > }
> >
> > /**
> > @@ -325,10 +366,12 @@ public class ZipFile {
> > */
> > public InputStream getInputStream(ZipArchiveEntry ze)
> > throws IOException, ZipException {
> > - OffsetEntry offsetEntry = entries.get(ze);
> > - if (offsetEntry == null) {
> > + if (!(ze instanceof Entry)) {
> > return null;
> > }
> > + // checked just above
> > + @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
> > + ((Entry) ze).getOffsetEntry();
> > ZipUtil.checkRequestedFeatures(ze);
> > long start = offsetEntry.dataOffset;
> > BoundedInputStream bis =
> > @@ -474,7 +517,8 @@ public class ZipFile {
> > throws IOException {
> > archive.readFully(CFH_BUF);
> > int off = 0;
> > - ZipArchiveEntry ze = new ZipArchiveEntry();
> > + OffsetEntry offset = new OffsetEntry();
> > + Entry ze = new Entry(offset);
> >
> > int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
> > off += SHORT;
> > @@ -529,10 +573,9 @@ public class ZipFile {
> > ze.setName(entryEncoding.decode(fileName), fileName);
> >
> > // LFH offset,
> > - OffsetEntry offset = new OffsetEntry();
> > offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
> > // data offset will be filled later
> > - entries.put(ze, offset);
> > + entries.add(ze);
> >
> > byte[] cdExtraData = new byte[extraLen];
> > archive.readFully(cdExtraData);
> > @@ -851,16 +894,11 @@ public class ZipFile {
> > private void resolveLocalFileHeaderData(Map<ZipArchiveEntry,
> NameAndComment>
> > entriesWithoutUTF8Flag)
> > throws IOException {
> > - // changing the name of a ZipArchiveEntry is going to change
> > - // the hashcode - see COMPRESS-164
> > - // Map needs to be reconstructed in order to keep central
> > - // directory order
> > - Map<ZipArchiveEntry, OffsetEntry> origMap =
> > - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
> > - entries.clear();
> > - for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent :
> origMap.entrySet()) {
> > - ZipArchiveEntry ze = ent.getKey();
> > - OffsetEntry offsetEntry = ent.getValue();
> > + for (Iterator<ZipArchiveEntry> it = entries.iterator();
> it.hasNext(); ) {
> > + // entries is filled in populateFromCentralDirectory and
> > + // never modified
> > + @SuppressWarnings("unchecked") Entry ze = (Entry) it.next();
> > + OffsetEntry offsetEntry = ze.getOffsetEntry();
> > long offset = offsetEntry.headerOffset;
> > archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
> > archive.readFully(SHORT_BUF);
> > @@ -883,13 +921,18 @@ public class ZipFile {
> > + SHORT + SHORT + fileNameLen + extraFieldLen;
> >
> > if (entriesWithoutUTF8Flag.containsKey(ze)) {
> > - String orig = ze.getName();
> > NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
> > ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
> > nc.comment);
> > }
> > - entries.put(ze, offsetEntry);
> > - nameMap.put(ze.getName(), ze);
> > +
> > + String name = ze.getName();
> > + Deque<ZipArchiveEntry> entriesOfThatName =
> nameMap.get(name);
> > + if (entriesOfThatName == null) {
> > + entriesOfThatName = new LinkedList<ZipArchiveEntry>();
> > + nameMap.put(name, entriesOfThatName);
> > + }
> > + entriesOfThatName.addLast(ze);
> > }
> > }
> >
> > @@ -996,16 +1039,54 @@ public class ZipFile {
> > return 0;
> > }
> >
> > - OffsetEntry off1 = entries.get(e1);
> > - OffsetEntry off2 = entries.get(e2);
> > - if (off1 == null) {
> > + @SuppressWarnings("unchecked") Entry ent1 =
> > + e1 instanceof Entry ? (Entry) e1 : null;
> > + @SuppressWarnings("unchecked") Entry ent2 =
> > + e2 instanceof Entry ? (Entry) e2 : null;
> > + if (ent1 == null) {
> > return 1;
> > }
> > - if (off2 == null) {
> > + if (ent2 == null) {
> > return -1;
> > }
> > - long val = (off1.headerOffset - off2.headerOffset);
> > + long val = (ent1.getOffsetEntry().headerOffset
> > + - ent2.getOffsetEntry().headerOffset);
> > return val == 0 ? 0 : val < 0 ? -1 : +1;
> > }
> > };
> > +
> > + /**
> > + * Extends ZipArchiveEntry to store the offset within the archive.
> > + */
> > + private static class Entry extends ZipArchiveEntry {
> > +
> > + private final OffsetEntry offsetEntry;
> > +
> > + Entry(OffsetEntry offset) {
> > + this.offsetEntry = offset;
> > + }
> > +
> > + OffsetEntry getOffsetEntry() {
> > + return offsetEntry;
> > + }
> > +
> > + @Override
> > + public int hashCode() {
> > + return 3 * super.hashCode()
> > + + (int) (offsetEntry.headerOffset % Integer.MAX_VALUE);
> > + }
> > +
> > + @Override
> > + public boolean equals(Object other) {
> > + if (super.equals(other)) {
> > + // super.equals would return false otherwise
> > + @SuppressWarnings("unchecked") Entry otherEntry =
> (Entry) other;
> > + return offsetEntry.headerOffset
> > + == otherEntry.offsetEntry.headerOffset
> > + && offsetEntry.dataOffset
> > + == otherEntry.offsetEntry.dataOffset;
> > + }
> > + return false;
> > + }
> > + }
> > }
> >
> > Modified:
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> > URL:
> http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> >
> ==============================================================================
> > ---
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> (original)
> > +++
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> Sat May 25 17:47:00 2013
> > @@ -27,6 +27,7 @@ import java.io.OutputStream;
> > import java.util.ArrayList;
> > import java.util.Collections;
> > import java.util.Enumeration;
> > +import java.util.Iterator;
> > import java.util.TreeMap;
> > import java.util.zip.ZipEntry;
> >
> > @@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
> > ZipArchiveEntry ze = zf.getEntry("test1.txt");
> > assertNotNull(ze);
> > assertNotNull(zf.getInputStream(ze));
> > +
> > + int numberOfEntries = 0;
> > + for (Iterator it = zf.getEntries("test1.txt"); it.hasNext();
> it.next()) {
> > + numberOfEntries++;
> > + }
> > + assertEquals(2, numberOfEntries);
> > }
> >
> > /*
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>
--
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by sebb <se...@gmail.com>.
Turns out that a List is sufficient; no need for a Deque.
Fixed in http://svn.apache.org/r1487167
On 28 May 2013 19:08, sebb <se...@gmail.com> wrote:
> On 25 May 2013 18:47, <bo...@apache.org> wrote:
>> Author: bodewig
>> Date: Sat May 25 17:47:00 2013
>> New Revision: 1486348
>>
>> URL: http://svn.apache.org/r1486348
>> Log:
>> provide access to all entries of a given name in ZipFile, COMPRESS-227
>
> -1, see below
>
>> Modified:
>> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>>
>> Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
>> URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
>> ==============================================================================
>> --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java (original)
>> +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Sat May 25 17:47:00 2013
>> @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
>> import java.util.Arrays;
>> import java.util.Collections;
>> import java.util.Comparator;
>> +import java.util.Deque;
>
> That requires Java 1.6; Compress currently targets 1.5
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: svn commit: r1486348 - in /commons/proper/compress/trunk/src:
main/java/org/apache/commons/compress/archivers/zip/ZipFile.java test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
Posted by sebb <se...@gmail.com>.
On 25 May 2013 18:47, <bo...@apache.org> wrote:
> Author: bodewig
> Date: Sat May 25 17:47:00 2013
> New Revision: 1486348
>
> URL: http://svn.apache.org/r1486348
> Log:
> provide access to all entries of a given name in ZipFile, COMPRESS-227
-1, see below
> Modified:
> commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
>
> Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
> URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> ==============================================================================
> --- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java (original)
> +++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java Sat May 25 17:47:00 2013
> @@ -25,9 +25,12 @@ import java.io.RandomAccessFile;
> import java.util.Arrays;
> import java.util.Collections;
> import java.util.Comparator;
> +import java.util.Deque;
That requires Java 1.6; Compress currently targets 1.5
> import java.util.Enumeration;
> import java.util.HashMap;
> -import java.util.LinkedHashMap;
> +import java.util.Iterator;
> +import java.util.LinkedList;
> +import java.util.List;
> import java.util.Map;
> import java.util.zip.Inflater;
> import java.util.zip.InflaterInputStream;
> @@ -83,17 +86,17 @@ public class ZipFile {
> private static final int POS_3 = 3;
>
> /**
> - * Maps ZipArchiveEntrys to two longs, recording the offsets of
> - * the local file headers and the start of entry data.
> + * List of entries in the order they appear inside the central
> + * directory.
> */
> - private final Map<ZipArchiveEntry, OffsetEntry> entries =
> - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(HASH_SIZE);
> + private final List<ZipArchiveEntry> entries =
> + new LinkedList<ZipArchiveEntry>();
>
> /**
> - * Maps String to ZipArchiveEntrys, name -> actual entry.
> + * Maps String to list of ZipArchiveEntrys, name -> actual entries.
> */
> - private final Map<String, ZipArchiveEntry> nameMap =
> - new HashMap<String, ZipArchiveEntry>(HASH_SIZE);
> + private final Map<String, Deque<ZipArchiveEntry>> nameMap =
> + new HashMap<String, Deque<ZipArchiveEntry>>(HASH_SIZE);
>
> private static final class OffsetEntry {
> private long headerOffset = -1;
> @@ -273,7 +276,7 @@ public class ZipFile {
> * @return all entries as {@link ZipArchiveEntry} instances
> */
> public Enumeration<ZipArchiveEntry> getEntries() {
> - return Collections.enumeration(entries.keySet());
> + return Collections.enumeration(entries);
> }
>
> /**
> @@ -287,8 +290,7 @@ public class ZipFile {
> * @since 1.1
> */
> public Enumeration<ZipArchiveEntry> getEntriesInPhysicalOrder() {
> - ZipArchiveEntry[] allEntries =
> - entries.keySet().toArray(new ZipArchiveEntry[0]);
> + ZipArchiveEntry[] allEntries = entries.toArray(new ZipArchiveEntry[0]);
> Arrays.sort(allEntries, OFFSET_COMPARATOR);
> return Collections.enumeration(Arrays.asList(allEntries));
> }
> @@ -296,12 +298,51 @@ public class ZipFile {
> /**
> * Returns a named entry - or {@code null} if no entry by
> * that name exists.
> + *
> + * <p>If multiple entries with the same name exist the first entry
> + * in the archive's central directory by that name is
> + * returned.</p>
> + *
> * @param name name of the entry.
> * @return the ZipArchiveEntry corresponding to the given name - or
> * {@code null} if not present.
> */
> public ZipArchiveEntry getEntry(String name) {
> - return nameMap.get(name);
> + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> + return entriesOfThatName != null ? entriesOfThatName.getFirst() : null;
> + }
> +
> + /**
> + * Returns all named entries in the same order they appear within
> + * the archive's central directory.
> + *
> + * @param name name of the entry.
> + * @return the Iterator<ZipArchiveEntry> corresponding to the
> + * given name
> + * @since 1.6
> + */
> + public Iterator<ZipArchiveEntry> getEntries(String name) {
> + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> + return entriesOfThatName != null ? entriesOfThatName.iterator()
> + : Collections.<ZipArchiveEntry>emptyList().iterator();
> + }
> +
> + /**
> + * Returns all named entries in the same order their contents
> + * appear within the archive.
> + *
> + * @param name name of the entry.
> + * @return the Iterator<ZipArchiveEntry> corresponding to the
> + * given name
> + * @since 1.6
> + */
> + public Iterator<ZipArchiveEntry> getEntriesInPhysicalOrder(String name) {
> + ZipArchiveEntry[] entriesOfThatName = new ZipArchiveEntry[0];
> + if (nameMap.containsKey(name)) {
> + entriesOfThatName = nameMap.get(name).toArray(entriesOfThatName);
> + Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
> + }
> + return Arrays.asList(entriesOfThatName).iterator();
> }
>
> /**
> @@ -325,10 +366,12 @@ public class ZipFile {
> */
> public InputStream getInputStream(ZipArchiveEntry ze)
> throws IOException, ZipException {
> - OffsetEntry offsetEntry = entries.get(ze);
> - if (offsetEntry == null) {
> + if (!(ze instanceof Entry)) {
> return null;
> }
> + // checked just above
> + @SuppressWarnings("unchecked") OffsetEntry offsetEntry =
> + ((Entry) ze).getOffsetEntry();
> ZipUtil.checkRequestedFeatures(ze);
> long start = offsetEntry.dataOffset;
> BoundedInputStream bis =
> @@ -474,7 +517,8 @@ public class ZipFile {
> throws IOException {
> archive.readFully(CFH_BUF);
> int off = 0;
> - ZipArchiveEntry ze = new ZipArchiveEntry();
> + OffsetEntry offset = new OffsetEntry();
> + Entry ze = new Entry(offset);
>
> int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
> off += SHORT;
> @@ -529,10 +573,9 @@ public class ZipFile {
> ze.setName(entryEncoding.decode(fileName), fileName);
>
> // LFH offset,
> - OffsetEntry offset = new OffsetEntry();
> offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
> // data offset will be filled later
> - entries.put(ze, offset);
> + entries.add(ze);
>
> byte[] cdExtraData = new byte[extraLen];
> archive.readFully(cdExtraData);
> @@ -851,16 +894,11 @@ public class ZipFile {
> private void resolveLocalFileHeaderData(Map<ZipArchiveEntry, NameAndComment>
> entriesWithoutUTF8Flag)
> throws IOException {
> - // changing the name of a ZipArchiveEntry is going to change
> - // the hashcode - see COMPRESS-164
> - // Map needs to be reconstructed in order to keep central
> - // directory order
> - Map<ZipArchiveEntry, OffsetEntry> origMap =
> - new LinkedHashMap<ZipArchiveEntry, OffsetEntry>(entries);
> - entries.clear();
> - for (Map.Entry<ZipArchiveEntry, OffsetEntry> ent : origMap.entrySet()) {
> - ZipArchiveEntry ze = ent.getKey();
> - OffsetEntry offsetEntry = ent.getValue();
> + for (Iterator<ZipArchiveEntry> it = entries.iterator(); it.hasNext(); ) {
> + // entries is filled in populateFromCentralDirectory and
> + // never modified
> + @SuppressWarnings("unchecked") Entry ze = (Entry) it.next();
> + OffsetEntry offsetEntry = ze.getOffsetEntry();
> long offset = offsetEntry.headerOffset;
> archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
> archive.readFully(SHORT_BUF);
> @@ -883,13 +921,18 @@ public class ZipFile {
> + SHORT + SHORT + fileNameLen + extraFieldLen;
>
> if (entriesWithoutUTF8Flag.containsKey(ze)) {
> - String orig = ze.getName();
> NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
> ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
> nc.comment);
> }
> - entries.put(ze, offsetEntry);
> - nameMap.put(ze.getName(), ze);
> +
> + String name = ze.getName();
> + Deque<ZipArchiveEntry> entriesOfThatName = nameMap.get(name);
> + if (entriesOfThatName == null) {
> + entriesOfThatName = new LinkedList<ZipArchiveEntry>();
> + nameMap.put(name, entriesOfThatName);
> + }
> + entriesOfThatName.addLast(ze);
> }
> }
>
> @@ -996,16 +1039,54 @@ public class ZipFile {
> return 0;
> }
>
> - OffsetEntry off1 = entries.get(e1);
> - OffsetEntry off2 = entries.get(e2);
> - if (off1 == null) {
> + @SuppressWarnings("unchecked") Entry ent1 =
> + e1 instanceof Entry ? (Entry) e1 : null;
> + @SuppressWarnings("unchecked") Entry ent2 =
> + e2 instanceof Entry ? (Entry) e2 : null;
> + if (ent1 == null) {
> return 1;
> }
> - if (off2 == null) {
> + if (ent2 == null) {
> return -1;
> }
> - long val = (off1.headerOffset - off2.headerOffset);
> + long val = (ent1.getOffsetEntry().headerOffset
> + - ent2.getOffsetEntry().headerOffset);
> return val == 0 ? 0 : val < 0 ? -1 : +1;
> }
> };
> +
> + /**
> + * Extends ZipArchiveEntry to store the offset within the archive.
> + */
> + private static class Entry extends ZipArchiveEntry {
> +
> + private final OffsetEntry offsetEntry;
> +
> + Entry(OffsetEntry offset) {
> + this.offsetEntry = offset;
> + }
> +
> + OffsetEntry getOffsetEntry() {
> + return offsetEntry;
> + }
> +
> + @Override
> + public int hashCode() {
> + return 3 * super.hashCode()
> + + (int) (offsetEntry.headerOffset % Integer.MAX_VALUE);
> + }
> +
> + @Override
> + public boolean equals(Object other) {
> + if (super.equals(other)) {
> + // super.equals would return false otherwise
> + @SuppressWarnings("unchecked") Entry otherEntry = (Entry) other;
> + return offsetEntry.headerOffset
> + == otherEntry.offsetEntry.headerOffset
> + && offsetEntry.dataOffset
> + == otherEntry.offsetEntry.dataOffset;
> + }
> + return false;
> + }
> + }
> }
>
> Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java
> URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java?rev=1486348&r1=1486347&r2=1486348&view=diff
> ==============================================================================
> --- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java (original)
> +++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java Sat May 25 17:47:00 2013
> @@ -27,6 +27,7 @@ import java.io.OutputStream;
> import java.util.ArrayList;
> import java.util.Collections;
> import java.util.Enumeration;
> +import java.util.Iterator;
> import java.util.TreeMap;
> import java.util.zip.ZipEntry;
>
> @@ -214,6 +215,12 @@ public class ZipFileTest extends TestCas
> ZipArchiveEntry ze = zf.getEntry("test1.txt");
> assertNotNull(ze);
> assertNotNull(zf.getInputStream(ze));
> +
> + int numberOfEntries = 0;
> + for (Iterator it = zf.getEntries("test1.txt"); it.hasNext(); it.next()) {
> + numberOfEntries++;
> + }
> + assertEquals(2, numberOfEntries);
> }
>
> /*
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org