On 28 May 2013 19:28, Gary Gregory <garydgreg...@gmail.com> wrote: > On Tue, May 28, 2013 at 2:22 PM, sebb <seb...@gmail.com> wrote: > >> On 28 May 2013 19:15, Gary Gregory <garydgreg...@gmail.com> wrote: >> > On Tue, May 28, 2013 at 2:08 PM, sebb <seb...@gmail.com> wrote: >> > >> >> 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 >> >> >> > >> > 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-unsubscr...@commons.apache.org >> >> For additional commands, e-mail: dev-h...@commons.apache.org >> >> >> >> >> > >> > >> > -- >> > E-Mail: garydgreg...@gmail.com | ggreg...@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-unsubscr...@commons.apache.org >> For additional commands, e-mail: dev-h...@commons.apache.org >> >> > > > -- > E-Mail: garydgreg...@gmail.com | ggreg...@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-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org