On 25 May 2013 18:47,  <bode...@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-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to