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