This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
commit 47e008b116bed7c3cf7cb3873f57c0852463fde3 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Wed Jul 3 11:05:15 2024 -0400 Reduce internal code duplication - Add ArchiveOutputStream.isFinished() - Add ArchiveOutputStream.checkFinished() - Rename private method --- src/changes/changes.xml | 2 + .../compress/archivers/ArchiveOutputStream.java | 33 +++++++++++- .../archivers/ar/ArArchiveOutputStream.java | 18 ++----- .../archivers/cpio/CpioArchiveOutputStream.java | 61 ++++++++-------------- .../archivers/tar/TarArchiveOutputStream.java | 30 +++-------- .../archivers/zip/ZipArchiveOutputStream.java | 7 ++- 6 files changed, 71 insertions(+), 80 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 103217cbb..bc878ef6f 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,8 @@ The <action> type attribute can be add,update,fix,remove. <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveInputStream.forEach(IOConsumer).</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveInputStream.iterator().</action> + <action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveOutputStream.isFinished().</action> + <action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveOutputStream.checkFinished().</action> <!-- UPDATE --> <action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump org.apache.commons:commons-parent from 69 to 71 #537.</action> <action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump PMD from 6.x to 7.2.0.</action> diff --git a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java index 038a2ea42..c7adb6c15 100644 --- a/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/ArchiveOutputStream.java @@ -59,6 +59,11 @@ public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends Filter /** Holds the number of bytes written to this stream. */ private long bytesWritten; + /** + * Whether this instance was successfully finished. + */ + private boolean finished; + /** * Constructs a new instance without a backing OutputStream. * <p> @@ -95,6 +100,18 @@ public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends Filter return true; } + /** + * Throws an {@link IOException} if this instance is already finished. + * + * @throws IOException if this instance is already finished. + * @since 1.27.0 + */ + protected void checkFinished() throws IOException { + if (isFinished()) { + throw new IOException("Stream has already been finished."); + } + } + /** * Closes the archive entry, writing any trailer information that may be required. * @@ -162,9 +179,11 @@ public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends Filter /** * Finishes the addition of entries to this stream, without closing it. Additional data can be written, if the format supports it. * - * @throws IOException if the user forgets to close the entry. + * @throws IOException Maybe thrown by subclasses if the user forgets to close the entry. */ - public abstract void finish() throws IOException; + public void finish() throws IOException { + finished = true; + } /** * Gets the current number of bytes written to this stream. @@ -187,6 +206,16 @@ public abstract class ArchiveOutputStream<E extends ArchiveEntry> extends Filter return (int) bytesWritten; } + /** + * Tests whether this instance was successfully finished. + * + * @return whether this instance was successfully finished. + * @since 1.27.0 + */ + protected boolean isFinished() { + return finished; + } + /** * Writes the headers for an archive entry to the output stream. The caller must then write the content to the stream and call {@link #closeArchiveEntry()} * to complete the process. diff --git a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java index 61445a363..30b813d63 100644 --- a/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/ar/ArArchiveOutputStream.java @@ -52,22 +52,10 @@ public class ArArchiveOutputStream extends ArchiveOutputStream<ArArchiveEntry> { private boolean prevEntryOpen; private int longFileMode = LONGFILE_ERROR; - /** Indicates if this archive is finished */ - private boolean finished; - public ArArchiveOutputStream(final OutputStream out) { super(out); } - /** - * @throws IOException - */ - private void checkFinished() throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } - } - private String checkLength(final String value, final int max, final String name) throws IOException { if (value.length() > max) { throw new IOException(name + " too long"); @@ -81,12 +69,12 @@ public class ArArchiveOutputStream extends ArchiveOutputStream<ArArchiveEntry> { @Override public void close() throws IOException { try { - if (!finished) { + if (!isFinished()) { finish(); } } finally { - out.close(); prevEntry = null; + out.close(); } } @@ -125,7 +113,7 @@ public class ArArchiveOutputStream extends ArchiveOutputStream<ArArchiveEntry> { throw new IOException("This archive contains unclosed entries."); } checkFinished(); - finished = true; + super.finish(); } private int pad(final int offset, final int newOffset, final char fill) throws IOException { diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java index b0528a252..df4e773de 100644 --- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveOutputStream.java @@ -73,9 +73,6 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr private boolean closed; - /** Indicates if this archive is finished */ - private boolean finished; - /** * See {@link CpioArchiveEntry#CpioArchiveEntry(short)} for possible values. */ @@ -171,6 +168,17 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr this(out, FORMAT_NEW, BLOCK_SIZE, encoding); } + /** + * Check to make sure that this stream has not been closed + * + * @throws IOException if the stream is already closed + */ + private void checkOpen() throws IOException { + if (this.closed) { + throw new IOException("Stream closed"); + } + } + /** * Closes the CPIO output stream as well as the stream being filtered. * @@ -179,7 +187,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr @Override public void close() throws IOException { try { - if (!finished) { + if (!isFinished()) { finish(); } } finally { @@ -197,12 +205,8 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public void closeArchiveEntry() throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } - - ensureOpen(); - + checkFinished(); + checkOpen(); if (entry == null) { throw new IOException("Trying to close non-existent entry"); } @@ -226,9 +230,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public CpioArchiveEntry createArchiveEntry(final File inputFile, final String entryName) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); return new CpioArchiveEntry(inputFile, entryName); } @@ -239,9 +241,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public CpioArchiveEntry createArchiveEntry(final Path inputPath, final String entryName, final LinkOption... options) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); return new CpioArchiveEntry(inputPath, entryName, options); } @@ -258,17 +258,6 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr return Arrays.copyOfRange(buf.array(), buf.arrayOffset(), buf.arrayOffset() + len); } - /** - * Check to make sure that this stream has not been closed - * - * @throws IOException if the stream is already closed - */ - private void ensureOpen() throws IOException { - if (this.closed) { - throw new IOException("Stream closed"); - } - } - /** * Finishes writing the contents of the CPIO output stream without closing the underlying stream. Use this method when applying multiple filters in * succession to the same output stream. @@ -277,10 +266,8 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public void finish() throws IOException { - ensureOpen(); - if (finished) { - throw new IOException("This archive has already been finished"); - } + checkOpen(); + checkFinished(); if (this.entry != null) { throw new IOException("This archive contains unclosed entries."); @@ -295,8 +282,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr if (lengthOfLastBlock != 0) { pad(blockSize - lengthOfLastBlock); } - - finished = true; + super.finish(); } private void pad(final int count) throws IOException { @@ -317,11 +303,8 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public void putArchiveEntry(final CpioArchiveEntry entry) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } - - ensureOpen(); + checkFinished(); + checkOpen(); if (this.entry != null) { closeArchiveEntry(); // close previous entry } @@ -353,7 +336,7 @@ public class CpioArchiveOutputStream extends ArchiveOutputStream<CpioArchiveEntr */ @Override public void write(final byte[] b, final int off, final int len) throws IOException { - ensureOpen(); + checkOpen(); if (off < 0 || len < 0 || off > b.length - len) { throw new IndexOutOfBoundsException(); } diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java index 82838af1f..5fb1c226d 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java @@ -117,11 +117,6 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> private boolean haveUnclosedEntry; - /** - * indicates if this archive is finished - */ - private boolean finished; - private final CountingOutputStream countingOut; private final ZipEncoding zipEncoding; @@ -299,7 +294,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> @Override public void close() throws IOException { try { - if (!finished) { + if (!isFinished()) { finish(); } } finally { @@ -319,9 +314,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> */ @Override public void closeArchiveEntry() throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); if (!haveUnclosedEntry) { throw new IOException("No current entry to close"); } @@ -340,17 +333,13 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> @Override public TarArchiveEntry createArchiveEntry(final File inputFile, final String entryName) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); return new TarArchiveEntry(inputFile, entryName); } @Override public TarArchiveEntry createArchiveEntry(final Path inputPath, final String entryName, final LinkOption... options) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); return new TarArchiveEntry(inputPath, entryName, options); } @@ -411,10 +400,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> */ @Override public void finish() throws IOException { - if (finished) { - throw new IOException("This archive has already been finished"); - } - + checkFinished(); if (haveUnclosedEntry) { throw new IOException("This archive contains unclosed entries."); } @@ -422,7 +408,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> writeEOFRecord(); padAsNeeded(); out.flush(); - finished = true; + super.finish(); } @Override @@ -528,9 +514,7 @@ public class TarArchiveOutputStream extends ArchiveOutputStream<TarArchiveEntry> */ @Override public void putArchiveEntry(final TarArchiveEntry archiveEntry) throws IOException { - if (finished) { - throw new IOException("Stream has already been finished"); - } + checkFinished(); if (archiveEntry.isGlobalPaxHeader()) { final byte[] data = encodeExtendedPaxHeadersContents(archiveEntry.getExtraPaxHeaders()); archiveEntry.setSize(data.length); diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java index bd0a5ad45..732fa2cf7 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java @@ -255,7 +255,12 @@ public class ZipArchiveOutputStream extends ArchiveOutputStream<ZipArchiveEntry> */ static final byte[] ZIP64_EOCD_LOC_SIG = ZipLong.getBytes(0X07064B50L); // NOSONAR - /** Indicates if this archive is finished. protected for use in Jar implementation */ + /** + * Indicates if this archive is finished. protected for use in Jar implementation. + * + * @deprecated See {@link #isFinished()} and {@link #finish()}. + */ + @Deprecated protected boolean finished; /**