diff --git a/gradle.properties b/gradle.properties index 2a004ed..f484bf3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = org.xbib name = archive -version = 1.0.0 +version = 1.0.1 gradle.wrapper.version = 6.4.1 diff --git a/gradle/compile/java.gradle b/gradle/compile/java.gradle index 9c8798d..c9bba7f 100644 --- a/gradle/compile/java.gradle +++ b/gradle/compile/java.gradle @@ -35,7 +35,7 @@ artifacts { } tasks.withType(JavaCompile) { - options.compilerArgs << '-Xlint:all' + options.compilerArgs << '-Xlint:all,-fallthrough' } javadoc { diff --git a/io-archive-cpio/src/main/java/org/xbib/io/archive/cpio/CpioArchiveInputStream.java b/io-archive-cpio/src/main/java/org/xbib/io/archive/cpio/CpioArchiveInputStream.java index 86e4468..001b8e4 100644 --- a/io-archive-cpio/src/main/java/org/xbib/io/archive/cpio/CpioArchiveInputStream.java +++ b/io-archive-cpio/src/main/java/org/xbib/io/archive/cpio/CpioArchiveInputStream.java @@ -1,6 +1,5 @@ package org.xbib.io.archive.cpio; -import org.xbib.io.archive.entry.ArchiveEntry; import org.xbib.io.archive.stream.ArchiveInputStream; import org.xbib.io.archive.util.ArchiveUtils; @@ -33,7 +32,7 @@ import java.io.InputStream; * Note: This implementation should be compatible to cpio 2.5 */ -public class CpioArchiveInputStream extends ArchiveInputStream implements CpioConstants { +public class CpioArchiveInputStream extends ArchiveInputStream implements CpioConstants { private boolean closed = false; @@ -380,7 +379,7 @@ public class CpioArchiveInputStream extends ArchiveInputStream implements CpioCo } @Override - public ArchiveEntry getNextEntry() throws IOException { + public CpioArchiveEntry getNextEntry() throws IOException { return getNextCPIOEntry(); } diff --git a/io-archive-dump/src/main/java/module-info.java b/io-archive-dump/src/main/java/module-info.java index 8526138..861f204 100644 --- a/io-archive-dump/src/main/java/module-info.java +++ b/io-archive-dump/src/main/java/module-info.java @@ -1,4 +1,4 @@ module org.xbib.io.archive.dump { exports org.xbib.io.archive.dump; - requires org.xbib.io.archive; + requires transitive org.xbib.io.archive; } diff --git a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveException.java b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveException.java index 3d3fa68..6ddd003 100644 --- a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveException.java +++ b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveException.java @@ -2,10 +2,10 @@ package org.xbib.io.archive.dump; import java.io.IOException; - /** * Dump Archive Exception */ +@SuppressWarnings("serial") public class DumpArchiveException extends IOException { public DumpArchiveException(String msg) { diff --git a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveInputStream.java b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveInputStream.java index 54d2298..d178660 100644 --- a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveInputStream.java +++ b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/DumpArchiveInputStream.java @@ -19,9 +19,9 @@ import java.util.Stack; * the archive, and the read each entry as a normal input stream * using read(). */ -public class DumpArchiveInputStream extends ArchiveInputStream { +public class DumpArchiveInputStream extends ArchiveInputStream { - private DumpArchiveSummary summary; + private final DumpArchiveSummary summary; private DumpArchiveEntry active; @@ -35,7 +35,7 @@ public class DumpArchiveInputStream extends ArchiveInputStream { private int readIdx; - private byte[] readBuf = new byte[DumpArchiveConstants.TP_SIZE]; + private final byte[] readBuf = new byte[DumpArchiveConstants.TP_SIZE]; private byte[] blockBuffer; @@ -46,13 +46,13 @@ public class DumpArchiveInputStream extends ArchiveInputStream { protected TapeInputStream raw; // map of ino -> dirent entry. We can use this to reconstruct full paths. - private Map names = new HashMap(); + private final Map names = new HashMap(); // map of ino -> (directory) entry when we're missing one or more elements in the path. - private Map pending = new HashMap(); + private final Map pending = new HashMap(); // queue of (directory) entries where we now have the full path. - private Queue queue; + private final Queue queue; /** * Constructor. diff --git a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/InvalidFormatException.java b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/InvalidFormatException.java index 0f34bda..635070a 100644 --- a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/InvalidFormatException.java +++ b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/InvalidFormatException.java @@ -1,11 +1,10 @@ - package org.xbib.io.archive.dump; - /** * Invalid Format Exception. There was an error decoding a * tape segment header. */ +@SuppressWarnings("serial") public class InvalidFormatException extends DumpArchiveException { protected long offset; diff --git a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/TapeInputStream.java b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/TapeInputStream.java index 7e070ad..ab2c44e 100644 --- a/io-archive-dump/src/main/java/org/xbib/io/archive/dump/TapeInputStream.java +++ b/io-archive-dump/src/main/java/org/xbib/io/archive/dump/TapeInputStream.java @@ -8,18 +8,24 @@ import java.util.Arrays; import java.util.zip.DataFormatException; import java.util.zip.Inflater; - /** * Filter stream that mimics a physical tape drive capable of compressing * the data stream */ -class TapeInputStream extends FilterInputStream { +public class TapeInputStream extends FilterInputStream { + private byte[] blockBuffer = new byte[DumpArchiveConstants.TP_SIZE]; + private int currBlkIdx = -1; + private int blockSize = DumpArchiveConstants.TP_SIZE; + private int recordSize = DumpArchiveConstants.TP_SIZE; + private int readOffset = DumpArchiveConstants.TP_SIZE; + private boolean isCompressed = false; + private long bytesRead = 0; /** diff --git a/io-archive-jar/src/main/java/module-info.java b/io-archive-jar/src/main/java/module-info.java index 45c7030..fbff0a9 100644 --- a/io-archive-jar/src/main/java/module-info.java +++ b/io-archive-jar/src/main/java/module-info.java @@ -1,5 +1,4 @@ module org.xbib.io.archive.jar { exports org.xbib.io.archive.jar; - requires org.xbib.io.archive; - requires org.xbib.io.archive.zip; + requires transitive org.xbib.io.archive.zip; } diff --git a/io-archive-jar/src/main/java/org/xbib/io/archive/jar/JarArchiveInputStream.java b/io-archive-jar/src/main/java/org/xbib/io/archive/jar/JarArchiveInputStream.java index c745ad4..3c3ef93 100644 --- a/io-archive-jar/src/main/java/org/xbib/io/archive/jar/JarArchiveInputStream.java +++ b/io-archive-jar/src/main/java/org/xbib/io/archive/jar/JarArchiveInputStream.java @@ -1,7 +1,6 @@ package org.xbib.io.archive.jar; -import org.xbib.io.archive.entry.ArchiveEntry; import org.xbib.io.archive.zip.ZipArchiveEntry; import org.xbib.io.archive.zip.ZipArchiveInputStream; @@ -11,7 +10,7 @@ import java.io.InputStream; /** * Implements an input stream that can read entries from jar files. */ -public class JarArchiveInputStream extends ZipArchiveInputStream { +public class JarArchiveInputStream extends ZipArchiveInputStream { public JarArchiveInputStream(final InputStream inputStream) { super(inputStream); @@ -23,7 +22,7 @@ public class JarArchiveInputStream extends ZipArchiveInputStream { } @Override - public ArchiveEntry getNextEntry() throws IOException { + public JarArchiveEntry getNextEntry() throws IOException { return getNextJarEntry(); } diff --git a/io-archive-tar/src/main/java/module-info.java b/io-archive-tar/src/main/java/module-info.java index 835d958..e0a5a23 100644 --- a/io-archive-tar/src/main/java/module-info.java +++ b/io-archive-tar/src/main/java/module-info.java @@ -1,4 +1,4 @@ module org.xbib.io.archive.tar { exports org.xbib.io.archive.tar; - requires org.xbib.io.archive; + requires transitive org.xbib.io.archive; } diff --git a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveEntry.java b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveEntry.java index e1ff479..ba5ce4e 100644 --- a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveEntry.java +++ b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveEntry.java @@ -546,6 +546,207 @@ public class TarArchiveEntry implements TarConstants, ArchiveEntry { parseTarHeader(header, encoding, false); } + + /** + * Write an entry's header information to a header buffer. + * + * @param outbuf The tar entry header buffer to fill in. + * @param encoding encoding to use when writing the file name. + * @param starMode whether to use the star/GNU tar/BSD tar + * extension for numeric fields if their value doesn't fit in the + * maximum size of standard tar archives + */ + public void writeEntryHeader(byte[] outbuf, ArchiveEntryEncoding encoding, boolean starMode) throws IOException { + int offset = 0; + offset = ArchiveUtils.formatNameBytes(name, outbuf, offset, NAMELEN, encoding); + offset = writeEntryHeaderField(mode, outbuf, offset, MODELEN, starMode); + offset = writeEntryHeaderField(userId, outbuf, offset, UIDLEN, starMode); + offset = writeEntryHeaderField(groupId, outbuf, offset, GIDLEN, starMode); + offset = writeEntryHeaderField(size, outbuf, offset, SIZELEN, starMode); + offset = writeEntryHeaderField(modTime, outbuf, offset, MODTIMELEN, starMode); + int csOffset = offset; + for (int c = 0; c < CHKSUMLEN; ++c) { + outbuf[offset++] = (byte) ' '; + } + outbuf[offset++] = linkFlag; + offset = ArchiveUtils.formatNameBytes(linkName, outbuf, offset, NAMELEN, encoding); + offset = ArchiveUtils.formatNameBytes(MAGIC_POSIX, outbuf, offset, MAGICLEN); + offset = ArchiveUtils.formatNameBytes(version, outbuf, offset, VERSIONLEN); + offset = ArchiveUtils.formatNameBytes(userName, outbuf, offset, UNAMELEN, encoding); + offset = ArchiveUtils.formatNameBytes(groupName, outbuf, offset, GNAMELEN, encoding); + offset = writeEntryHeaderField(devMajor, outbuf, offset, DEVLEN, starMode); + offset = writeEntryHeaderField(devMinor, outbuf, offset, DEVLEN, starMode); + while (offset < outbuf.length) { + outbuf[offset++] = 0; + } + long chk = computeCheckSum(outbuf); + formatCheckSumOctalBytes(chk, outbuf, csOffset, CHKSUMLEN); + } + + private int writeEntryHeaderField(long value, byte[] outbuf, int offset, int length, boolean starMode) { + if (!starMode && (value < 0 + || value >= (1l << (3 * (length - 1))))) { + // value doesn't fit into field when written as octal + // number, will be written to PAX header or causes an + // error + return formatLongOctalBytes(0, outbuf, offset, length); + } + return formatLongOctalOrBinaryBytes(value, outbuf, offset, length); + } + + + /** + * Write an long integer into a buffer as an octal string if this + * will fit, or as a binary number otherwise. + *

+ * Uses {@link #formatUnsignedOctalString} to format + * the value as an octal string with leading zeros. + * The converted number is followed by a space. + * + * @param value The value to write into the buffer. + * @param buf The destination buffer. + * @param offset The starting offset into the buffer. + * @param length The length of the buffer. + * @return The updated offset. + * @throws IllegalArgumentException if the value (and trailer) + * will not fit in the buffer. + */ + private int formatLongOctalOrBinaryBytes(final long value, byte[] buf, final int offset, final int length) { + // Check whether we are dealing with UID/GID or SIZE field + final long maxAsOctalChar = length == UIDLEN ? MAXID : MAXSIZE; + final boolean negative = value < 0; + if (!negative && value <= maxAsOctalChar) { // OK to store as octal chars + return formatLongOctalBytes(value, buf, offset, length); + } + if (length < 9) { + formatLongBinary(value, buf, offset, length, negative); + } + formatBigIntegerBinary(value, buf, offset, length, negative); + buf[offset] = (byte) (negative ? 0xff : 0x80); + return offset + length; + } + + private void formatLongBinary(final long value, byte[] buf, final int offset, final int length, final boolean negative) { + final int bits = (length - 1) * 8; + final long max = 1l << bits; + long val = Math.abs(value); + if (val >= max) { + throw new IllegalArgumentException("Value " + value + + " is too large for " + length + " byte field."); + } + if (negative) { + val ^= max - 1; + val |= 0xff << bits; + val++; + } + for (int i = offset + length - 1; i >= offset; i--) { + buf[i] = (byte) val; + val >>= 8; + } + } + + private void formatBigIntegerBinary(final long value, byte[] buf, + final int offset, + final int length, + final boolean negative) { + BigInteger val = BigInteger.valueOf(value); + final byte[] b = val.toByteArray(); + final int len = b.length; + final int off = offset + length - len; + System.arraycopy(b, 0, buf, off, len); + final byte fill = (byte) (negative ? 0xff : 0); + for (int i = offset + 1; i < off; i++) { + buf[i] = fill; + } + } + + /** + * Writes an octal value into a buffer. + *

+ * Uses {@link #formatUnsignedOctalString} to format + * the value as an octal string with leading zeros. + * The converted number is followed by NUL and then space. + * + * @param value The value to convert + * @param buf The destination buffer + * @param offset The starting offset into the buffer. + * @param length The size of the buffer. + * @return The updated value of offset, i.e. offset+length + * @throws IllegalArgumentException if the value (and trailer) will not fit in the buffer + */ + private int formatCheckSumOctalBytes(final long value, byte[] buf, final int offset, final int length) { + int idx = length - 2; + formatUnsignedOctalString(value, buf, offset, idx); + buf[offset + idx++] = 0; + buf[offset + idx] = (byte) ' '; + return offset + length; + } + + /** + * Write an octal long integer into a buffer. + *

+ * Uses {@link #formatUnsignedOctalString} to format + * the value as an octal string with leading zeros. + * The converted number is followed by a space. + * + * @param value The value to write as octal + * @param buf The destinationbuffer. + * @param offset The starting offset into the buffer. + * @param length The length of the buffer + * @return The updated offset + * @throws IllegalArgumentException if the value (and trailer) will not fit in the buffer + */ + private int formatLongOctalBytes(final long value, byte[] buf, final int offset, final int length) { + int idx = length - 1; // For space + formatUnsignedOctalString(value, buf, offset, idx); + buf[offset + idx] = (byte) ' '; // Trailing space + return offset + length; + } + + /** + * Fill buffer with unsigned octal number, padded with leading zeroes. + * + * @param value number to convert to octal - treated as unsigned + * @param buffer destination buffer + * @param offset starting offset in buffer + * @param length length of buffer to fill + * @throws IllegalArgumentException if the value will not fit in the buffer + */ + private void formatUnsignedOctalString(final long value, byte[] buffer, final int offset, final int length) { + int remaining = length; + remaining--; + if (value == 0) { + buffer[offset + remaining--] = (byte) '0'; + } else { + long val = value; + for (; remaining >= 0 && val != 0; --remaining) { + buffer[offset + remaining] = (byte) ((byte) '0' + (byte) (val & 7)); + val = val >>> 3; + } + if (val != 0) { + throw new IllegalArgumentException(value + "=" + Long.toOctalString(value) + " will not fit in octal number buffer of length " + length); + } + } + + for (; remaining >= 0; --remaining) { // leading zeros + buffer[offset + remaining] = (byte) '0'; + } + } + + /** + * Compute the checksum of a tar entry header. + * + * @param buf The tar entry's header buffer. + * @return The computed checksum. + */ + private long computeCheckSum(final byte[] buf) { + long sum = 0; + for (byte aBuf : buf) { + sum += 255 & aBuf; + } + return sum; + } + private void parseTarHeader(byte[] header, ArchiveEntryEncoding encoding, final boolean oldStyle) throws IOException { int offset = 0; diff --git a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputEntry.java b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputEntry.java index 6e61642..9c84983 100644 --- a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputEntry.java +++ b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputEntry.java @@ -10,7 +10,7 @@ import java.math.BigInteger; import java.util.Date; /** - * This class represents an entry in a Tar archive for output + * This class represents an entry in a Tar archive for output. */ public class TarArchiveOutputEntry implements TarConstants, ArchiveEntry { diff --git a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputStream.java b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputStream.java index ce528fa..f57e0c3 100644 --- a/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputStream.java +++ b/io-archive-tar/src/main/java/org/xbib/io/archive/tar/TarArchiveOutputStream.java @@ -7,7 +7,7 @@ import org.xbib.io.archive.entry.ArchiveEntryEncodingHelper; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -15,7 +15,7 @@ import java.util.Map; /** * The TarOutputStream writes a UNIX tar archive as an output stream */ -public class TarArchiveOutputStream extends ArchiveOutputStream implements TarConstants { +public class TarArchiveOutputStream extends ArchiveOutputStream implements TarConstants { private static final ArchiveEntryEncoding ASCII = ArchiveEntryEncodingHelper.getEncoding("ASCII"); @@ -239,8 +239,8 @@ public class TarArchiveOutputStream extends ArchiveOutputStream= NAMELEN) { name = name.substring(0, NAMELEN - 1); } - TarArchiveOutputEntry pex = new TarArchiveOutputEntry(name, LF_PAX_EXTENDED_HEADER_LC); + TarArchiveEntry pex = new TarArchiveEntry(name, LF_PAX_EXTENDED_HEADER_LC); StringWriter w = new StringWriter(); for (Map.Entry h : headers.entrySet()) { String key = h.getKey(); @@ -449,7 +449,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream 100 // or where UTF-8 encoding isn't a single octet @@ -458,11 +458,11 @@ public class TarArchiveOutputStream extends ArchiveOutputStream paxHeaders, - TarArchiveOutputEntry entry) { + TarArchiveEntry entry) { addPaxHeaderForBigNumber(paxHeaders, "size", entry.getEntrySize(), MAXSIZE); addPaxHeaderForBigNumber(paxHeaders, "gid", entry.getGroupId(), MAXID); addPaxHeaderForBigNumber(paxHeaders, "mtime", entry.getLastModified().getTime() / 1000, MAXSIZE); @@ -519,7 +519,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream> implementations; static { - implementations = new HashMap>(); + implementations = new HashMap<>(); register(AsiExtraField.class); register(JarMarker.class); register(UnicodePathExtraField.class); @@ -37,14 +36,10 @@ public class ExtraFieldUtils { */ public static void register(Class c) { try { - ZipExtraField ze = (ZipExtraField) c.newInstance(); + ZipExtraField ze = (ZipExtraField) c.getDeclaredConstructor().newInstance(); implementations.put(ze.getHeaderId(), c); - } catch (ClassCastException cc) { - throw new RuntimeException(c + " doesn\'t implement ZipExtraField"); - } catch (InstantiationException ie) { - throw new RuntimeException(c + " is not a concrete class"); - } catch (IllegalAccessException ie) { - throw new RuntimeException(c + "\'s no-arg constructor is not public"); + } catch (Exception e) { + throw new RuntimeException(e); } } @@ -54,14 +49,13 @@ public class ExtraFieldUtils { * * @param headerId the header identifier * @return an instance of the appropiate ExtraField - * @throws InstantiationException if unable to instantiate the class - * @throws IllegalAccessException if not allowed to instatiate the class + * @throws Exception if unable to instantiate the class */ public static ZipExtraField createExtraField(ZipShort headerId) - throws InstantiationException, IllegalAccessException { + throws Exception { Class c = implementations.get(headerId); if (c != null) { - return (ZipExtraField) c.newInstance(); + return (ZipExtraField) c.getDeclaredConstructor().newInstance(); } UnrecognizedExtraField u = new UnrecognizedExtraField(); u.setHeaderId(headerId); @@ -157,7 +151,7 @@ public class ExtraFieldUtils { length); } v.add(ze); - } catch (InstantiationException | IllegalAccessException ie) { + } catch (Exception ie) { throw new ZipException(ie.getMessage()); } start += (length + WORD); diff --git a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/UnsupportedZipFeatureException.java b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/UnsupportedZipFeatureException.java index e3d1fe8..23fdc4d 100644 --- a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/UnsupportedZipFeatureException.java +++ b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/UnsupportedZipFeatureException.java @@ -7,6 +7,7 @@ import java.util.zip.ZipException; * Exception thrown when attempting to read or write data for a zip * entry that uses ZIP features not supported by this library. */ +@SuppressWarnings("serial") public class UnsupportedZipFeatureException extends ZipException { private final Feature reason; diff --git a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/Zip64RequiredException.java b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/Zip64RequiredException.java index be1c05b..5e81466 100644 --- a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/Zip64RequiredException.java +++ b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/Zip64RequiredException.java @@ -8,6 +8,7 @@ import java.util.zip.ZipException; * support to an archive and {@link ZipArchiveOutputStream#setUseZip64 * UseZip64} has been set to {@link Zip64Mode#Never Never}. */ +@SuppressWarnings("serial") public class Zip64RequiredException extends ZipException { /** diff --git a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveInputStream.java b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveInputStream.java index 648b1d9..4c12a72 100644 --- a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveInputStream.java +++ b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveInputStream.java @@ -1,6 +1,5 @@ package org.xbib.io.archive.zip; -import org.xbib.io.archive.entry.ArchiveEntry; import org.xbib.io.archive.stream.ArchiveInputStream; import org.xbib.io.archive.entry.ArchiveEntryEncoding; import org.xbib.io.archive.entry.ArchiveEntryEncodingHelper; @@ -34,7 +33,7 @@ import static org.xbib.io.archive.zip.ZipConstants.ZIP64_MAGIC; * * @see ZipFile */ -public class ZipArchiveInputStream extends ArchiveInputStream { +public class ZipArchiveInputStream extends ArchiveInputStream { /** * The zip encoding to use for filenames and the file comment. @@ -252,9 +251,10 @@ public class ZipArchiveInputStream extends ArchiveInputStream { } } + @SuppressWarnings("unchecked") @Override - public ArchiveEntry getNextEntry() throws IOException { - return getNextZipEntry(); + public E getNextEntry() throws IOException { + return (E) getNextZipEntry(); } @Override diff --git a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveOutputStream.java b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveOutputStream.java index 1dbfa13..af792e3 100644 --- a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveOutputStream.java +++ b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipArchiveOutputStream.java @@ -562,9 +562,10 @@ public class ZipArchiveOutputStream extends ArchiveOu raf.seek(save); } + @SuppressWarnings("unchecked") @Override public E newArchiveEntry() { - return (E)new ZipArchiveEntry(); + return (E) new ZipArchiveEntry(); } /** diff --git a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipFile.java b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipFile.java index 33161d5..f51da4d 100644 --- a/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipFile.java +++ b/io-archive-zip/src/main/java/org/xbib/io/archive/zip/ZipFile.java @@ -316,23 +316,6 @@ public class ZipFile { } } - /** - * Ensures that the close method of this zipfile is called when - * there are no more references to it. - * - * @see #close() - */ - @Override - protected void finalize() throws Throwable { - try { - if (!closed) { - close(); - } - } finally { - super.finalize(); - } - } - /** * Length of a "central directory" entry structure without file * name, extra fields or comment. @@ -370,8 +353,7 @@ public class ZipFile { */ private Map populateFromCentralDirectory() throws IOException { - HashMap noUTF8Flag = - new HashMap(); + HashMap noUTF8Flag = new HashMap<>(); positionAtCentralDirectory(); diff --git a/io-codec/src/main/java/module-info.java b/io-codec/src/main/java/module-info.java index 0623f1e..0231a06 100644 --- a/io-codec/src/main/java/module-info.java +++ b/io-codec/src/main/java/module-info.java @@ -1,4 +1,5 @@ module org.xbib.io.codec { + uses org.xbib.io.codec.StreamCodec; exports org.xbib.io.codec; exports org.xbib.io.codec.ar; exports org.xbib.io.codec.cpio; @@ -10,11 +11,10 @@ module org.xbib.io.codec { requires org.xbib.io.compress.lzf; requires org.xbib.io.compress.xz; requires org.xbib.io.compress.zlib; - requires org.xbib.io.archive; - requires org.xbib.io.archive.ar; - requires org.xbib.io.archive.cpio; - requires org.xbib.io.archive.dump; - requires org.xbib.io.archive.jar; - requires org.xbib.io.archive.tar; - requires org.xbib.io.archive.zip; + requires transitive org.xbib.io.archive.ar; + requires transitive org.xbib.io.archive.cpio; + requires transitive org.xbib.io.archive.dump; + requires transitive org.xbib.io.archive.jar; + requires transitive org.xbib.io.archive.tar; + requires transitive org.xbib.io.archive.zip; } diff --git a/io-codec/src/main/java/org/xbib/io/codec/ArchiveCodec.java b/io-codec/src/main/java/org/xbib/io/codec/ArchiveCodec.java index 745b9fb..60c3fbe 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/ArchiveCodec.java +++ b/io-codec/src/main/java/org/xbib/io/codec/ArchiveCodec.java @@ -1,5 +1,6 @@ package org.xbib.io.codec; +import org.xbib.io.archive.entry.ArchiveEntry; import org.xbib.io.archive.stream.ArchiveInputStream; import org.xbib.io.archive.stream.ArchiveOutputStream; import java.io.IOException; @@ -14,7 +15,7 @@ import java.io.OutputStream; * @param the archive input stream type * @param the archive output type */ -public interface ArchiveCodec { +public interface ArchiveCodec, O extends ArchiveOutputStream, S extends ArchiveSession> { /** * Returns the name of this archive codec ("cpio", "tar", "zip") @@ -23,14 +24,6 @@ public interface ArchiveCodec +public abstract class ArchiveSession, O extends ArchiveOutputStream> implements Session { - private final static StreamCodecService codecFactory = StreamCodecService.getInstance(); - private final static int DEFAULT_INPUT_BUFSIZE = 65536; protected int bufferSize = DEFAULT_INPUT_BUFSIZE; @@ -65,15 +32,13 @@ public abstract class ArchiveSession 0) { String name = packet.name(); - ArchiveEntry entry = getOutputStream().newArchiveEntry(); + E entry = getOutputStream().newArchiveEntry(); entry.setName(name); entry.setLastModified(new Date()); entry.setEntrySize(buf.length); diff --git a/io-codec/src/main/java/org/xbib/io/codec/Session.java b/io-codec/src/main/java/org/xbib/io/codec/Session.java index bde8f92..43fca24 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/Session.java +++ b/io-codec/src/main/java/org/xbib/io/codec/Session.java @@ -7,11 +7,11 @@ import java.io.IOException; * operations, and being closed. Sessions must be opened before the first * operation and closed after the last operation. */ -public interface Session

{ +public interface Session

{ enum Mode { - READ, WRITE, APPEND,CONTROL, DELETE; + READ, WRITE, APPEND, CONTROL, DELETE; } /** diff --git a/io-codec/src/main/java/org/xbib/io/codec/StreamCodecService.java b/io-codec/src/main/java/org/xbib/io/codec/StreamCodecService.java index f40db9d..1d9db62 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/StreamCodecService.java +++ b/io-codec/src/main/java/org/xbib/io/codec/StreamCodecService.java @@ -1,5 +1,7 @@ package org.xbib.io.codec; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Map; import java.util.ServiceLoader; import java.util.Set; @@ -10,13 +12,14 @@ import java.util.WeakHashMap; */ public class StreamCodecService { - private final static Map codecs = new WeakHashMap<>(); + private final static Map> codecs = new WeakHashMap<>(); private final static StreamCodecService instance = new StreamCodecService(); + @SuppressWarnings({"rawtypes","unchecked"}) private StreamCodecService() { ServiceLoader loader = ServiceLoader.load(StreamCodec.class); - for (StreamCodec codec : loader) { + for (StreamCodec codec : loader) { if (!codecs.containsKey(codec.getName())) { codecs.put(codec.getName(), codec); } @@ -27,7 +30,7 @@ public class StreamCodecService { return instance; } - public StreamCodec getCodec(String suffix) { + public StreamCodec getCodec(String suffix) { if (codecs.containsKey(suffix)) { return codecs.get(suffix); } diff --git a/io-codec/src/main/java/org/xbib/io/codec/ar/ArSession.java b/io-codec/src/main/java/org/xbib/io/codec/ar/ArSession.java index 57def9a..3b4f82b 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/ar/ArSession.java +++ b/io-codec/src/main/java/org/xbib/io/codec/ar/ArSession.java @@ -1,9 +1,9 @@ package org.xbib.io.codec.ar; +import org.xbib.io.archive.ar.ArArchiveEntry; import org.xbib.io.codec.ArchiveSession; import org.xbib.io.archive.ar.ArArchiveInputStream; import org.xbib.io.archive.ar.ArArchiveOutputStream; -import org.xbib.io.codec.Packet; import org.xbib.io.codec.Session; import org.xbib.io.codec.StringPacket; import java.io.InputStream; @@ -12,7 +12,7 @@ import java.io.OutputStream; /** * Ar Session */ -public class ArSession extends ArchiveSession +public class ArSession extends ArchiveSession implements Session { private final static String SUFFIX = "ar"; diff --git a/io-codec/src/main/java/org/xbib/io/codec/cpio/CpioSession.java b/io-codec/src/main/java/org/xbib/io/codec/cpio/CpioSession.java index de1d223..88ec153 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/cpio/CpioSession.java +++ b/io-codec/src/main/java/org/xbib/io/codec/cpio/CpioSession.java @@ -1,5 +1,6 @@ package org.xbib.io.codec.cpio; +import org.xbib.io.archive.cpio.CpioArchiveEntry; import org.xbib.io.codec.ArchiveSession; import org.xbib.io.archive.cpio.CpioArchiveInputStream; import org.xbib.io.archive.cpio.CpioArchiveOutputStream; @@ -9,7 +10,7 @@ import java.io.OutputStream; /** * Cpio Session */ -public class CpioSession extends ArchiveSession { +public class CpioSession extends ArchiveSession { private final static String SUFFIX = "cpio"; diff --git a/io-codec/src/main/java/org/xbib/io/codec/jar/JarSession.java b/io-codec/src/main/java/org/xbib/io/codec/jar/JarSession.java index f80c232..a5a0947 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/jar/JarSession.java +++ b/io-codec/src/main/java/org/xbib/io/codec/jar/JarSession.java @@ -1,12 +1,13 @@ package org.xbib.io.codec.jar; +import org.xbib.io.archive.jar.JarArchiveEntry; import org.xbib.io.codec.ArchiveSession; import org.xbib.io.archive.jar.JarArchiveInputStream; import org.xbib.io.archive.jar.JarArchiveOutputStream; import java.io.InputStream; import java.io.OutputStream; -public class JarSession extends ArchiveSession { +public class JarSession extends ArchiveSession { private final static String SUFFIX = "jar"; diff --git a/io-codec/src/main/java/org/xbib/io/codec/tar/TarSession.java b/io-codec/src/main/java/org/xbib/io/codec/tar/TarSession.java index c2b9155..a49c1c0 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/tar/TarSession.java +++ b/io-codec/src/main/java/org/xbib/io/codec/tar/TarSession.java @@ -31,6 +31,7 @@ */ package org.xbib.io.codec.tar; +import org.xbib.io.archive.tar.TarArchiveEntry; import org.xbib.io.codec.ArchiveSession; import org.xbib.io.archive.tar.TarArchiveInputStream; import org.xbib.io.archive.tar.TarArchiveOutputStream; @@ -38,7 +39,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -public class TarSession extends ArchiveSession { +public class TarSession extends ArchiveSession { private final static String SUFFIX = "tar"; diff --git a/io-codec/src/main/java/org/xbib/io/codec/zip/ZipSession.java b/io-codec/src/main/java/org/xbib/io/codec/zip/ZipSession.java index 56f4a75..6421b93 100644 --- a/io-codec/src/main/java/org/xbib/io/codec/zip/ZipSession.java +++ b/io-codec/src/main/java/org/xbib/io/codec/zip/ZipSession.java @@ -1,37 +1,37 @@ package org.xbib.io.codec.zip; +import org.xbib.io.archive.zip.ZipArchiveEntry; import org.xbib.io.codec.ArchiveSession; import org.xbib.io.archive.zip.ZipArchiveInputStream; import org.xbib.io.archive.zip.ZipArchiveOutputStream; import java.io.InputStream; import java.io.OutputStream; -public class ZipSession extends ArchiveSession { +public class ZipSession extends ArchiveSession, ZipArchiveOutputStream> { private final static String SUFFIX = "zip"; - private ZipArchiveInputStream in; + private ZipArchiveInputStream in; - private ZipArchiveOutputStream out; + private ZipArchiveOutputStream out; protected String getSuffix() { return SUFFIX; } protected void open(InputStream in) { - this.in = new ZipArchiveInputStream(in); + this.in = new ZipArchiveInputStream<>(in); } protected void open(OutputStream out) { - this.out = new ZipArchiveOutputStream(out); + this.out = new ZipArchiveOutputStream<>(out); } - public ZipArchiveInputStream getInputStream() { + public ZipArchiveInputStream getInputStream() { return in; } - public ZipArchiveOutputStream getOutputStream() { + public ZipArchiveOutputStream getOutputStream() { return out; } - } diff --git a/io-compress-lzf/src/main/java/org/xbib/io/compress/lzf/ChunkDecoderFactory.java b/io-compress-lzf/src/main/java/org/xbib/io/compress/lzf/ChunkDecoderFactory.java index b17a7b0..b9e6064 100644 --- a/io-compress-lzf/src/main/java/org/xbib/io/compress/lzf/ChunkDecoderFactory.java +++ b/io-compress-lzf/src/main/java/org/xbib/io/compress/lzf/ChunkDecoderFactory.java @@ -30,7 +30,7 @@ public class ChunkDecoderFactory { */ public static ChunkDecoder optimalInstance() { try { - return INSTANCE.implClass.newInstance(); + return INSTANCE.implClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new IllegalStateException("Failed to load a ChunkDecoder instance (" + e.getClass().getName() + "): " + e.getMessage(), e); diff --git a/io-compress-xz/src/main/java/org/xbib/io/compress/xz/IndexIndicatorException.java b/io-compress-xz/src/main/java/org/xbib/io/compress/xz/IndexIndicatorException.java index 0b24fba..f4ff3ea 100644 --- a/io-compress-xz/src/main/java/org/xbib/io/compress/xz/IndexIndicatorException.java +++ b/io-compress-xz/src/main/java/org/xbib/io/compress/xz/IndexIndicatorException.java @@ -1,5 +1,5 @@ - package org.xbib.io.compress.xz; +@SuppressWarnings("serial") class IndexIndicatorException extends Exception { } diff --git a/io-compress-xz/src/main/java/org/xbib/io/compress/xz/index/IndexEncoder.java b/io-compress-xz/src/main/java/org/xbib/io/compress/xz/index/IndexEncoder.java index 8862ecd..7babc99 100644 --- a/io-compress-xz/src/main/java/org/xbib/io/compress/xz/index/IndexEncoder.java +++ b/io-compress-xz/src/main/java/org/xbib/io/compress/xz/index/IndexEncoder.java @@ -1,4 +1,3 @@ - package org.xbib.io.compress.xz.index; import org.xbib.io.compress.xz.XZIOException; @@ -7,11 +6,12 @@ import org.xbib.io.compress.xz.common.EncoderUtil; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Iterator; +import java.util.List; import java.util.zip.CheckedOutputStream; public class IndexEncoder extends IndexBase { - private final ArrayList records = new ArrayList(); + + private final List records = new ArrayList<>(); public IndexEncoder() { super(new XZIOException("XZ Stream or its Index has grown too big")); @@ -34,8 +34,7 @@ public class IndexEncoder extends IndexBase { EncoderUtil.encodeVLI(outChecked, recordCount); // List of Records - for (Iterator i = records.iterator(); i.hasNext(); ) { - IndexRecord record = (IndexRecord) i.next(); + for (IndexRecord record : records) { EncoderUtil.encodeVLI(outChecked, record.unpadded); EncoderUtil.encodeVLI(outChecked, record.uncompressed); }