diff options
author | Sadaf Ebrahimi <sadafebrahimi@google.com> | 2023-10-12 16:22:41 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-10-12 16:22:41 +0000 |
commit | b2a374b6261dd971fd9af9c5bcd2c58c5a56771e (patch) | |
tree | 7db98c0abbad5bdc521c3b53b1caab409b95f330 | |
parent | 6d6f45c6e69f336f00cf49076ec3fd0e21502cd1 (diff) | |
parent | d189b34b4ef33514fd70966fad26c26b4d554bcf (diff) | |
download | apache-commons-io-b2a374b6261dd971fd9af9c5bcd2c58c5a56771e.tar.gz |
Upgrade apache-commons-io to rel/commons-io-2.14.0 am: f93b23c2f8 am: d189b34b4e
Original change: https://android-review.googlesource.com/c/platform/external/apache-commons-io/+/2780899
Change-Id: Ifbd68feaab381f4a0804680c47f0d2e98f7ed6d8
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
159 files changed, 2402 insertions, 1252 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2e4cbace..14204217 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,10 +45,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 with: persist-credentials: false - - uses: actions/cache@v3.3.1 + - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@04daf014b50eaf774287bf3f0f1869d4b4c4b913 # v2.21.7 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -68,7 +68,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@04daf014b50eaf774287bf3f0f1869d4b4c4b913 # v2.21.7 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -82,4 +82,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@04daf014b50eaf774287bf3f0f1869d4b4c4b913 # v2.21.7 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index ce7402a8..f100bf3f 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -29,17 +29,17 @@ jobs: java: [ 8 ] steps: - - uses: actions/checkout@v3.5.2 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 with: persist-credentials: false - - uses: actions/cache@v3.3.1 + - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v3.11.0 + uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: distribution: 'temurin' java-version: ${{ matrix.java }} @@ -47,6 +47,6 @@ jobs: run: mvn -V test jacoco:report --file pom.xml --no-transfer-progress - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # v3.1.4 with: files: ./target/site/jacoco/jacoco.xml diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 3088a451..6bd303e9 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -43,17 +43,17 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v3.5.2 + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 with: persist-credentials: false - - uses: actions/cache@v3.3.1 + - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven- - name: Set up JDK ${{ matrix.java }} - uses: actions/setup-java@v3.11.0 + uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0 with: distribution: 'temurin' java-version: ${{ matrix.java }} diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 672a3e46..3f533c0e 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -40,12 +40,12 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@v3.5.2 # 3.1.0 + uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 with: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@80e868c13c90f172d68d1f4501dee99e2479f7af # 2.1.3 + uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # 2.2.0 with: results_file: results.sarif results_format: sarif @@ -57,13 +57,13 @@ jobs: publish_results: true - name: "Upload artifact" - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # 3.1.2 + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # 3.1.3 with: name: SARIF file path: results.sarif retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b398f525a5587552e573b247ac661067fafa920b # 2.1.22 + uses: github/codeql-action/upload-sarif@04daf014b50eaf774287bf3f0f1869d4b4c4b913 # 2.21.7 with: sarif_file: results.sarif @@ -1,6 +1,6 @@ # This project was upgraded with external_updater. # Usage: tools/external_updater/updater.sh update apache-commons-io -# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md name: "apache-commons-io" description: "The Apache Commons IO library contains utility classes, stream implementations, file filters, file comparators, endian transformation classes, and much more." @@ -13,11 +13,11 @@ third_party { type: GIT value: "https://github.com/apache/commons-io.git" } - version: "rel/commons-io-2.13.0" + version: "rel/commons-io-2.14.0" license_type: NOTICE last_upgrade_date { year: 2023 - month: 6 - day: 30 + month: 10 + day: 11 } } @@ -46,7 +46,7 @@ Apache Commons IO [![GitHub Actions Status](https://github.com/apache/commons-io/workflows/Java%20CI/badge.svg)](https://github.com/apache/commons-io/actions) [![Coverage Status](https://codecov.io/gh/apache/commons-io/branch/master/graph/badge.svg)](https://app.codecov.io/gh/apache/commons-io) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/commons-io/commons-io/badge.svg?gav=true)](https://maven-badges.herokuapp.com/maven-central/commons-io/commons-io/?gav=true) -[![Javadocs](https://javadoc.io/badge/commons-io/commons-io/2.13.0.svg)](https://javadoc.io/doc/commons-io/commons-io/2.13.0) +[![Javadocs](https://javadoc.io/badge/commons-io/commons-io/2.14.0.svg)](https://javadoc.io/doc/commons-io/commons-io/2.14.0) [![CodeQL](https://github.com/apache/commons-io/workflows/CodeQL/badge.svg)](https://github.com/apache/commons-io/actions/workflows/codeql-analysis.yml?query=workflow%3ACodeQL) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/apache/commons-io/badge)](https://api.securityscorecards.dev/projects/github.com/apache/commons-io) @@ -70,7 +70,7 @@ Alternatively, you can pull it from the central Maven repositories: <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.13.0</version> + <version>2.14.0</version> </dependency> ``` @@ -89,7 +89,7 @@ You can learn more about contributing via GitHub in our [contribution guidelines License ------- -This code is under the [Apache Licence v2](https://www.apache.org/licenses/LICENSE-2.0). +This code is under the [Apache License v2](https://www.apache.org/licenses/LICENSE-2.0). See the `NOTICE.txt` file for required notices and attributions. diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 0b351a4b..8300ad4f 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,3 +1,83 @@ + +Apache Commons IO +Version 2.14.0 +Release Notes + +INTRODUCTION: + +Commons IO is a package of Java utility classes like java.io. +Classes in this package are considered to be so standard and of such high +reuse as to justify existence in java.io. + +The Apache Commons IO library contains utility classes, stream implementations, file filters, +file comparators, endian transformation classes, and much more. + +Java 8 required. + +Changes in this version include: + +New features: +o Add DeferredFileOutputStream.getPath(). Thanks to Gary Gregory. +o Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]). Thanks to Gary Gregory. +o Add IOUtils.skip[Fully](InputStream, long, Supplier<byte[]>). Thanks to Gary Gregory. +o Add FilesUncheck.find(Path, int, BiPredicate%lt;Path, BasicFileAttributes>, FileVisitOption...) Thanks to Gary Gregory. +o Add IOIntSupplier. Thanks to Gary Gregory. +o Add IOLongSupplier. Thanks to Gary Gregory. +o Add Uncheck.getAsInt(IOIntSupplier [, Supplier<String>]). Thanks to Gary Gregory. +o Add Uncheck.getAsLong(IOLongSupplier [, Supplier<String>]). Thanks to Gary Gregory. +o Add Uncheck.run(IORunnable, Supplier<String>) Thanks to Gary Gregory. +o Add Uncheck.get(IOSupplier, Supplier<String>) Thanks to Gary Gregory. +o IOFileFilter now also extends java.nio.file.PathMatcher. Thanks to Gary Gregory. +o Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher. Thanks to Gary Gregory. +o Add ThresholdingOutputStream.getOutputStream() and deprecate getStream(). Thanks to Gary Gregory. +o Add DeferredFileOutputStream.Builder.setOutputFile(Path). Thanks to Gary Gregory. +o Add DeferredFileOutputStream.Builder.setDirectory(Path). Thanks to Gary Gregory. +o Add AbstractStreamBuilder.setBufferSizeChecker(IntToIntFunction). Thanks to Gary Gregory. +o Add AbstractStreamBuilder.setBufferSizeMax(int). Thanks to Gary Gregory. + +Fixed Bugs: +o IO-799: ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1. Thanks to Jeroen van der Vegt, Gary Gregory. +o IO-804: FileUtils.forceMkdirParent() Javadoc is incorrect. Thanks to Elliotte Rusty Harold, Gary Gregory. +o [StepSecurity] ci: Harden GitHub Actions #461. Thanks to step-security-bot, Gary Gregory. +o MagicNumberFileFilter.accept(Path, BasicFileAttributes) doesn't its byteOffset before reading. Thanks to Gary Gregory. +o Javadoc improvements. Thanks to Gary Gregory. +o Spelling #468. Thanks to Josh Soref, Gary Gregory. +o Use assertThrows #475. Thanks to Jakub Kupczyk. + +Changes: +o Bump jimfs from 1.2 to 1.3.0 #465 (tests). Thanks to Dependabot. +o Bump commons-parent from 58 to 62. Thanks to Gary Gregory. +o Bump commons-lang3 from 3.12 to 3.13.0. Thanks to Gary Gregory. + +Compatibility with 2.6: +Binary compatible: Yes. +Source compatible: Yes. +Semantic compatible: Yes. + +Commons IO 2.9.0 requires Java 8. +Commons IO 2.8.0 requires Java 8. +Commons IO 2.7 requires Java 8. +Commons IO 2.6 requires Java 7. +Commons IO 2.5 requires Java 6. +Commons IO 2.4 requires Java 6. +Commons IO 2.3 requires Java 6. +Commons IO 2.2 requires Java 5. +Commons IO 1.4 requires Java 1.3. + +Historical list of changes: https://commons.apache.org/proper/commons-io/changes-report.html + +For complete information on Apache Commons IO, including instructions on how to submit bug reports, +patches, or suggestions for improvement, see the Apache Commons IO website: + +https://commons.apache.org/proper/commons-io/ + +Download page: https://commons.apache.org/proper/commons-io/download_io.cgi + +Have fun! +-Apache Commons Team + +============================================================================== + Apache Commons IO Version 2.13.0 Release Notes @@ -1747,7 +1827,7 @@ Enhancements from 1.0 - LockableFileWriter - encoding support [36825] Add support for character encodings to LockableFileWriter Improve the validation - Create directories if necesssary + Create directories if necessary - IOUtils and EndianUtils are no longer final [28978] Allows developers to have subclasses if desired @@ -19,12 +19,12 @@ <parent> <groupId>org.apache.commons</groupId> <artifactId>commons-parent</artifactId> - <version>58</version> + <version>62</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.13.0</version> + <version>2.14.0</version> <name>Apache Commons IO</name> <inceptionYear>2002</inceptionYear> @@ -265,13 +265,13 @@ file comparators, endian transformation classes, and much more. <dependency> <groupId>com.google.jimfs</groupId> <artifactId>jimfs</artifactId> - <version>1.2</version> + <version>1.3.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.12.0</version> + <version>3.13.0</version> <scope>test</scope> </dependency> <dependency> @@ -294,8 +294,8 @@ file comparators, endian transformation classes, and much more. <commons.componentid>io</commons.componentid> <commons.module.name>org.apache.commons.io</commons.module.name> <commons.rc.version>RC1</commons.rc.version> - <commons.bc.version>2.12.0</commons.bc.version> - <commons.release.version>2.13.0</commons.release.version> + <commons.bc.version>2.13.0</commons.bc.version> + <commons.release.version>2.14.0</commons.release.version> <commons.release.desc>(requires Java 8)</commons.release.desc> <commons.jira.id>IO</commons.jira.id> <commons.jira.pid>12310477</commons.jira.pid> @@ -324,7 +324,7 @@ file comparators, endian transformation classes, and much more. <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory> <commons.javadoc.java.link>${commons.javadoc8.java.link}</commons.javadoc.java.link> <commons.moditect.version>1.0.0.Final</commons.moditect.version> - <jmh.version>1.36</jmh.version> + <jmh.version>1.37</jmh.version> <japicmp.skip>false</japicmp.skip> <jacoco.skip>${env.JACOCO_SKIP}</jacoco.skip> <commons.release.isDistModule>true</commons.release.isDistModule> diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f9ff3ae3..28efbb7d 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -47,6 +47,92 @@ The <action> type attribute can be add,update,fix,remove. </properties> <body> + <release version="2.14.0" date="2023-09-24" description="Java 8 required."> + <!-- FIX --> + <action dev="ggregory" type="fix" issue="IO-799" due-to="Jeroen van der Vegt, Gary Gregory"> + ReaderInputStream.read() throws an exception instead of returning -1 when called again after returning -1. + </action> + <action dev="ggregory" type="fix" issue="IO-804" due-to="Elliotte Rusty Harold, Gary Gregory"> + FileUtils.forceMkdirParent() Javadoc is incorrect. + </action> + <action dev="ggregory" type="fix" due-to="step-security-bot, Gary Gregory"> + [StepSecurity] ci: Harden GitHub Actions #461. + </action> + <action dev="ggregory" type="fix" due-to="Gary Gregory"> + MagicNumberFileFilter.accept(Path, BasicFileAttributes) doesn't set its byteOffset before reading. + </action> + <action dev="ggregory" type="fix" due-to="Gary Gregory"> + Javadoc improvements. + </action> + <action dev="ggregory" type="fix" due-to="Josh Soref, Gary Gregory"> + Spelling #468. + </action> + <action dev="ggregory" type="fix" due-to="Jakub Kupczyk"> + Use assertThrows #475. + </action> + <!-- ADD --> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add DeferredFileOutputStream.getPath(). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add FileCleaningTracker.track(Path, Object[, FileDeleteStrategy]). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add IOUtils.skip[Fully](InputStream, long, Supplier<byte[]>). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add FilesUncheck.find(Path, int, BiPredicate%lt;Path, BasicFileAttributes>, FileVisitOption...) + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add IOIntSupplier. + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add IOLongSupplier. + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add Uncheck.getAsInt(IOIntSupplier [, Supplier<String>]). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add Uncheck.getAsLong(IOLongSupplier [, Supplier<String>]). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add Uncheck.run(IORunnable, Supplier<String>) + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add Uncheck.get(IOSupplier, Supplier<String>) + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + IOFileFilter now also extends java.nio.file.PathMatcher. + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add PathMatcherFileFilter to adapt java.nio.file.PathMatcher. + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add ThresholdingOutputStream.getOutputStream() and deprecate getStream(). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add DeferredFileOutputStream.Builder.setOutputFile(Path). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add DeferredFileOutputStream.Builder.setDirectory(Path). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add AbstractStreamBuilder.setBufferSizeChecker(IntToIntFunction). + </action> + <action dev="ggregory" type="add" due-to="Gary Gregory"> + Add AbstractStreamBuilder.setBufferSizeMax(int). + </action> + <!-- UPDATE --> + <action dev="ggregory" type="update" due-to="Dependabot"> + Bump jimfs from 1.2 to 1.3.0 #465 (tests). + </action> + <action dev="ggregory" type="update" due-to="Gary Gregory"> + Bump commons-parent from 58 to 62. + </action> + <action type="update" dev="ggregory" due-to="Gary Gregory"> + Bump commons-lang3 from 3.12 to 3.13.0. + </action> + </release> <release version="2.13.0" date="2023-06-03" description="Java 8 required."> <!-- FIX --> <action issue="IO-791" dev="ggregory" type="fix" due-to="Chad Wilson, Gary Gregory"> @@ -62,10 +148,10 @@ The <action> type attribute can be add,update,fix,remove. FileAlreadyExistsException in PathUtils.createParentDirectories(Path, LinkOption, FileAttribute...). </action> <action dev="ggregory" type="fix" due-to="Gary Gregory"> - Only read the relevant portion of a file in AbstractOrigin.FileOrigin.getByteArray(long, int) + Only read the relevant portion of a file in AbstractOrigin.FileOrigin.getByteArray(long, int). </action> <action dev="ggregory" type="fix" due-to="Gary Gregory"> - Only read the relevant portion of a file in AbstractOrigin.PathOrigin.getByteArray(long, int) + Only read the relevant portion of a file in AbstractOrigin.PathOrigin.getByteArray(long, int). </action> <action dev="ggregory" type="fix" due-to="Shai Shapira, Gary Gregory" issue="IO-798"> DeferredFileOutputStream throws exception when system temp dir is a symlink. @@ -76,6 +162,12 @@ The <action> type attribute can be add,update,fix,remove. <action dev="ggregory" type="fix" due-to="Gary Gregory"> ReaderInputStream.Builder.setCharset(null) should reset to a default object, not throw an NPE. </action> + <action dev="ggregory" type="fix" issue="IO-800" due-to="Jan Høydahl, Gary Gregory"> + Fix back-incompatible change for PathUtils.deleteDirectory(): throw NoSuchFileException instead of IllegalArgumentException #459. + </action> + <action dev="ggregory" type="fix" issue="IO-801" due-to="James Howe, Gary Gregory"> + Deprecation documentation gives incorrect alternative. + </action> <!-- ADD --> <action dev="ggregory" type="add" due-to="Gary Gregory"> Add CharSequenceInputStream.Builder. diff --git a/src/changes/release-notes.vm b/src/changes/release-notes.vm index 5739b66f..86973814 100644 --- a/src/changes/release-notes.vm +++ b/src/changes/release-notes.vm @@ -166,3 +166,5 @@ Download page: ${project.url}download_io.cgi Have fun! -Apache Commons Team + +============================================================================== diff --git a/src/conf/checkstyle.xml b/src/conf/checkstyle.xml index bbc848f5..d2fc3923 100644 --- a/src/conf/checkstyle.xml +++ b/src/conf/checkstyle.xml @@ -16,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. --> <!DOCTYPE module PUBLIC - "-//Checkstyle//DTD Checkstyle Configuration 1.2//EN" - "https://checkstyle.org/dtds/configuration_1_2.dtd"> + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="localeLanguage" value="en" /> <module name="JavadocPackage"> diff --git a/src/main/java/org/apache/commons/io/FileCleaningTracker.java b/src/main/java/org/apache/commons/io/FileCleaningTracker.java index 5d7ad0ed..98c33b0d 100644 --- a/src/main/java/org/apache/commons/io/FileCleaningTracker.java +++ b/src/main/java/org/apache/commons/io/FileCleaningTracker.java @@ -19,6 +19,7 @@ package org.apache.commons.io; import java.io.File; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -228,7 +229,7 @@ public class FileCleaningTracker { } /** - * Track the specified file, using the provided marker, deleting the file + * Tracks the specified file, using the provided marker, deleting the file * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * @@ -260,6 +261,36 @@ public class FileCleaningTracker { * when the marker instance is garbage collected. * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @throws NullPointerException if the file is null + * @since 2.14.0 + */ + public void track(final Path file, final Object marker) { + track(file, marker, null); + } + + /** + * Tracks the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The specified deletion strategy is used. + * + * @param file the file to be tracked, not null + * @param marker the marker object used to track the file, not null + * @param deleteStrategy the strategy to delete the file, null means normal + * @throws NullPointerException if the file is null + * @since 2.14.0 + */ + public void track(final Path file, final Object marker, final FileDeleteStrategy deleteStrategy) { + Objects.requireNonNull(file, "file"); + addTracker(file.toAbsolutePath().toString(), marker, deleteStrategy); + } + + /** + * Tracks the specified file, using the provided marker, deleting the file + * when the marker instance is garbage collected. + * The {@link FileDeleteStrategy#NORMAL normal} deletion strategy will be used. + * * @param path the full path to the file to be tracked, not null * @param marker the marker object used to track the file, not null * @throws NullPointerException if the path is null diff --git a/src/main/java/org/apache/commons/io/FileSystem.java b/src/main/java/org/apache/commons/io/FileSystem.java index d71bd373..c7dbdfa8 100644 --- a/src/main/java/org/apache/commons/io/FileSystem.java +++ b/src/main/java/org/apache/commons/io/FileSystem.java @@ -215,7 +215,7 @@ public enum FileSystem { * (this.codePointAt(<i>k</i>) == searchChar) && (<i>k</i> >= start) * </pre></blockquote> * <p> - * is true. In either case, if no such character occurs inm {@code cs} + * is true. In either case, if no such character occurs in {@code cs} * at or after position {@code start}, then * {@code -1} is returned. * </p> diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java index ef1f5082..807dc37c 100644 --- a/src/main/java/org/apache/commons/io/FileUtils.java +++ b/src/main/java/org/apache/commons/io/FileUtils.java @@ -1088,8 +1088,8 @@ public class FileUtils { } /** - * Creates all parent directories for a File object, including any necessary but nonexistent parent directories. If a parent directory already exists or is - * null, nothing happens. + * Creates all parent directories for a File object, including any necessary but non-existent parent directories. If a parent directory already exists or + * is null, nothing happens. * * @param file the File that may need parents, may be null. * @return The parent directory, or {@code null} if the given File does have a parent. @@ -1281,7 +1281,7 @@ public class FileUtils { /** * Internal copy directory method. Creates all destination parent directories, - * including any necessary but nonexistent parent directories. + * including any necessary but non-existent parent directories. * * @param srcDir the validated source directory, must not be {@code null}. * @param destDir the validated destination directory, must not be {@code null}. @@ -1364,7 +1364,7 @@ public class FileUtils { } /** - * Creates all directories for a File object, including any necessary but nonexistent parent directories. If the {@code directory} already exists or is + * Creates all directories for a File object, including any necessary but non-existent parent directories. If the {@code directory} already exists or is * null, nothing happens. * <p> * Calls {@link File#mkdirs()} and throws an {@link IOException} on failure. @@ -1381,16 +1381,15 @@ public class FileUtils { } /** - * Calls {@link File#mkdirs()} and throws an {@link IOException} on failure. - * <p> - * Creates all directories for a File object, including any necessary but nonexistent parent directories. If the {@code directory} already exists or is + * Creates all directories for a File object, including any necessary but non-existent parent directories. If the parent directory already exists or is * null, nothing happens. + * <p> + * Calls {@link File#mkdirs()} for the parent of @{code file}. * </p> * * @param file file with parents to create, must not be {@code null}. * @throws NullPointerException if the file is {@code null}. * @throws IOException if the directory was not created along with all its parent directories. - * @throws IOException if the given file object is not a directory. * @throws SecurityException See {@link File#mkdirs()}. * @see File#mkdirs() * @since 2.5 @@ -2271,7 +2270,7 @@ public class FileUtils { /** * Calls {@link File#mkdirs()} and throws an {@link IOException} on failure. * <p> - * Creates all directories for a File object, including any necessary but nonexistent parent directories. If the {@code directory} already exists or is + * Creates all directories for a File object, including any necessary but non-existent parent directories. If the {@code directory} already exists or is * null, nothing happens. * </p> * @@ -2323,7 +2322,7 @@ public class FileUtils { /** * Moves a directory to another directory. * <p> - * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but nonexistent parent directories. + * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but non-existent parent directories. * </p> * * @param source the file to be moved. @@ -2408,7 +2407,7 @@ public class FileUtils { /** * Moves a file to a directory. * <p> - * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but nonexistent parent directories. + * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but non-existent parent directories. * </p> * * @param srcFile the file to be moved. @@ -2437,7 +2436,7 @@ public class FileUtils { /** * Moves a file or directory to a destination directory. * <p> - * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but nonexistent parent directories. + * If {@code createDestDir} is true, creates all destination parent directories, including any necessary but non-existent parent directories. * </p> * <p> * When the destination is on another file system, do a "copy and delete". diff --git a/src/main/java/org/apache/commons/io/IOExceptionList.java b/src/main/java/org/apache/commons/io/IOExceptionList.java index ca3f8800..8ee519b5 100644 --- a/src/main/java/org/apache/commons/io/IOExceptionList.java +++ b/src/main/java/org/apache/commons/io/IOExceptionList.java @@ -65,7 +65,7 @@ public class IOExceptionList extends IOException implements Iterable<Throwable> private final List<? extends Throwable> causeList; /** - * Creates a new exception caused by a list of exceptions. + * Constructs a new exception caused by a list of exceptions. * * @param causeList a list of cause exceptions. */ @@ -74,7 +74,7 @@ public class IOExceptionList extends IOException implements Iterable<Throwable> } /** - * Creates a new exception caused by a list of exceptions. + * Constructs a new exception caused by a list of exceptions. * * @param message The detail message, see {@link #getMessage()}. * @param causeList a list of cause exceptions. diff --git a/src/main/java/org/apache/commons/io/IOIndexedException.java b/src/main/java/org/apache/commons/io/IOIndexedException.java index 71253d43..9a85328e 100644 --- a/src/main/java/org/apache/commons/io/IOIndexedException.java +++ b/src/main/java/org/apache/commons/io/IOIndexedException.java @@ -45,7 +45,7 @@ public class IOIndexedException extends IOException { private final int index; /** - * Creates a new exception. + * Constructs a new exception. * * @param index index of this exception. * @param cause cause exceptions. diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java index a8d8ffb2..b6b6f137 100644 --- a/src/main/java/org/apache/commons/io/IOUtils.java +++ b/src/main/java/org/apache/commons/io/IOUtils.java @@ -52,8 +52,10 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.zip.InflaterInputStream; import org.apache.commons.io.function.IOConsumer; import org.apache.commons.io.function.IOSupplier; @@ -2375,6 +2377,36 @@ public class IOUtils { * @since 2.0 */ public static long skip(final InputStream input, final long toSkip) throws IOException { + return skip(input, toSkip, IOUtils::getScratchByteArrayWriteOnly); + } + + /** + * Skips bytes from an input byte stream. + * <p> + * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the + * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads. + * </p> + * <p> + * This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case for skip() implementations + * in subclasses of {@link InputStream}. + * </p> + * <p> + * Note that the implementation uses {@link InputStream#read(byte[], int, int)} rather than delegating to {@link InputStream#skip(long)}. This means that + * the method may be considerably less efficient than using the actual skip implementation, this is done to guarantee that the correct number of bytes are + * skipped. + * </p> + * + * @param input byte stream to skip + * @param toSkip number of bytes to skip. + * @param skipBufferSupplier Supplies the buffer to use for reading. + * @return number of bytes actually skipped. + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @see InputStream#skip(long) + * @see <a href="https://issues.apache.org/jira/browse/IO-203">IO-203 - Add skipFully() method for InputStreams</a> + * @since 2.14.0 + */ + public static long skip(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException { if (toSkip < 0) { throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip); } @@ -2385,9 +2417,9 @@ public class IOUtils { // long remain = toSkip; while (remain > 0) { + final byte[] skipBuffer = skipBufferSupplier.get(); // See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip() - final byte[] byteArray = getScratchByteArrayWriteOnly(); - final long n = input.read(byteArray, 0, (int) Math.min(remain, byteArray.length)); + final long n = input.read(skipBuffer, 0, (int) Math.min(remain, skipBuffer.length)); if (n < 0) { // EOF break; } @@ -2485,10 +2517,40 @@ public class IOUtils { * @since 2.0 */ public static void skipFully(final InputStream input, final long toSkip) throws IOException { + final long skipped = skip(input, toSkip, IOUtils::getScratchByteArrayWriteOnly); + if (skipped != toSkip) { + throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); + } + } + + /** + * Skips the requested number of bytes or fail if there are not enough left. + * <p> + * Intended for special cases when customization of the temporary buffer is needed because, for example, a nested input stream has requirements for the + * bytes read. For example, when using {@link InflaterInputStream}s from multiple threads. + * </p> + * <p> + * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF). + * </p> + * <p> + * Note that the implementation uses {@link #skip(InputStream, long)}. This means that the method may be considerably less efficient than using the actual + * skip implementation, this is done to guarantee that the correct number of characters are skipped. + * </p> + * + * @param input stream to skip + * @param toSkip the number of bytes to skip + * @param skipBufferSupplier Supplies the buffer to use for reading. + * @throws IOException if there is a problem reading the file + * @throws IllegalArgumentException if toSkip is negative + * @throws EOFException if the number of bytes skipped was incorrect + * @see InputStream#skip(long) + * @since 2.14.0 + */ + public static void skipFully(final InputStream input, final long toSkip, final Supplier<byte[]> skipBufferSupplier) throws IOException { if (toSkip < 0) { throw new IllegalArgumentException("Bytes to skip must not be negative: " + toSkip); } - final long skipped = skip(input, toSkip); + final long skipped = skip(input, toSkip, skipBufferSupplier); if (skipped != toSkip) { throw new EOFException("Bytes to skip: " + toSkip + " actual: " + skipped); } diff --git a/src/main/java/org/apache/commons/io/RandomAccessFileMode.java b/src/main/java/org/apache/commons/io/RandomAccessFileMode.java index bb2c1236..54061588 100644 --- a/src/main/java/org/apache/commons/io/RandomAccessFileMode.java +++ b/src/main/java/org/apache/commons/io/RandomAccessFileMode.java @@ -57,7 +57,7 @@ public enum RandomAccessFileMode { } /** - * Creates a random access file stream to read from, and optionally to write to, the file specified by the {@link File} + * Constructs a random access file stream to read from, and optionally to write to, the file specified by the {@link File} * argument. * * @param file the file object @@ -69,7 +69,7 @@ public enum RandomAccessFileMode { } /** - * Creates a random access file stream to read from, and optionally to write to, the file specified by the {@link File} + * Constructs a random access file stream to read from, and optionally to write to, the file specified by the {@link File} * argument. * * @param file the file object @@ -81,7 +81,7 @@ public enum RandomAccessFileMode { } /** - * Creates a random access file stream to read from, and optionally to write to, the file specified by the {@link File} + * Constructs a random access file stream to read from, and optionally to write to, the file specified by the {@link File} * argument. * * @param file the file object diff --git a/src/main/java/org/apache/commons/io/TaggedIOException.java b/src/main/java/org/apache/commons/io/TaggedIOException.java index 43d7730f..9c95d326 100644 --- a/src/main/java/org/apache/commons/io/TaggedIOException.java +++ b/src/main/java/org/apache/commons/io/TaggedIOException.java @@ -103,7 +103,7 @@ public class TaggedIOException extends IOExceptionWithCause { private final Serializable tag; /** - * Creates a tagged wrapper for the given exception. + * Constructs a tagged wrapper for the given exception. * * @param original the exception to be tagged * @param tag tag of this exception diff --git a/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java b/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java index 797213ff..97271af6 100644 --- a/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java +++ b/src/main/java/org/apache/commons/io/UncheckedIOExceptions.java @@ -29,7 +29,7 @@ import java.util.Objects; final class UncheckedIOExceptions { /** - * Creates a new UncheckedIOException for the given detail message. + * Constructs a new UncheckedIOException for the given detail message. * <p> * This method exists because there is no String constructor in {@link UncheckedIOException}. * </p> @@ -43,7 +43,7 @@ final class UncheckedIOExceptions { } /** - * Creates a new UncheckedIOException for the given detail message. + * Constructs a new UncheckedIOException for the given detail message. * <p> * This method exists because there is no String constructor in {@link UncheckedIOException}. * </p> diff --git a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java index bc79dba5..bd823713 100644 --- a/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java +++ b/src/main/java/org/apache/commons/io/build/AbstractOriginSupplier.java @@ -46,7 +46,7 @@ import org.apache.commons.io.build.AbstractOrigin.WriterOrigin; public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier<T, B>> extends AbstractSupplier<T, B> { /** - * Creates a new byte array origin for a byte array. + * Constructs a new byte array origin for a byte array. * * @param origin the byte array. * @return a new byte array origin. @@ -56,7 +56,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new CharSequence origin for a CharSequence. + * Constructs a new CharSequence origin for a CharSequence. * * @param origin the CharSequence. * @return a new file origin. @@ -67,7 +67,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new file origin for a file. + * Constructs a new file origin for a file. * * @param origin the file. * @return a new file origin. @@ -77,7 +77,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new file origin for a file path. + * Constructs a new file origin for a file path. * * @param origin the file path. * @return a new file origin. @@ -87,7 +87,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new input stream origin for a file. + * Constructs a new input stream origin for a file. * * @param origin the input stream. * @return a new input stream origin. @@ -97,7 +97,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new output stream origin for a file. + * Constructs a new output stream origin for a file. * * @param origin the output stream. * @return a new output stream origin. @@ -107,7 +107,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new path origin for a file. + * Constructs a new path origin for a file. * * @param origin the path. * @return a new path origin. @@ -117,7 +117,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new path name origin for a path name. + * Constructs a new path name origin for a path name. * * @param origin the path name. * @return a new path name origin. @@ -127,7 +127,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new reader origin for a reader. + * Constructs a new reader origin for a reader. * * @param origin the reader. * @return a new reader origin. @@ -137,7 +137,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new reader origin for a URI. + * Constructs a new reader origin for a URI. * * @param origin the URI. * @return a new URI origin. @@ -147,7 +147,7 @@ public abstract class AbstractOriginSupplier<T, B extends AbstractOriginSupplier } /** - * Creates a new writer origin for a file. + * Constructs a new writer origin for a file. * * @param origin the writer. * @return a new writer . diff --git a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java index 8beccd93..d94638ac 100644 --- a/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java +++ b/src/main/java/org/apache/commons/io/build/AbstractStreamBuilder.java @@ -24,6 +24,7 @@ import java.io.Writer; import java.nio.charset.Charset; import java.nio.file.OpenOption; import java.nio.file.Path; +import java.util.function.IntUnaryOperator; import org.apache.commons.io.Charsets; import org.apache.commons.io.IOUtils; @@ -38,6 +39,8 @@ import org.apache.commons.io.file.PathUtils; */ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T, B>> extends AbstractOriginSupplier<T, B> { + private static final int DEFAULT_MAX_VALUE = Integer.MAX_VALUE; + private static final OpenOption[] DEFAULT_OPEN_OPTIONS = PathUtils.EMPTY_OPEN_OPTION_ARRAY; /** @@ -51,6 +54,11 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T private int bufferSizeDefault = IOUtils.DEFAULT_BUFFER_SIZE; /** + * The maximum buffer size. + */ + private int bufferSizeMax = DEFAULT_MAX_VALUE; + + /** * The Charset, defaults to {@link Charset#defaultCharset()}. */ private Charset charset = Charset.defaultCharset(); @@ -63,6 +71,26 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T private OpenOption[] openOptions = DEFAULT_OPEN_OPTIONS; /** + * The default checking behavior for a buffer size request. Throws a {@link IllegalArgumentException} by default. + */ + private final IntUnaryOperator defaultSizeChecker = size -> size > bufferSizeMax ? throwIae(size, bufferSizeMax) : size; + + /** + * The checking behavior for a buffer size request. + */ + private IntUnaryOperator bufferSizeChecker = defaultSizeChecker; + + /** + * Applies the buffer size request. + * + * @param size the size request. + * @return the size to use, usually the input, or can throw an unchecked exception, like {@link IllegalArgumentException}. + */ + private int checkBufferSize(final int size) { + return bufferSizeChecker.applyAsInt(size); + } + + /** * Gets the buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}). * * @return the buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}). @@ -86,7 +114,7 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T * @return An input stream * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a CharSequence. - * @throws IllegalStateException if the {@code origin} is {@code null}. + * @throws IllegalStateException if the {@code origin} is {@code null}. * @see AbstractOrigin#getCharSequence(Charset) * @since 2.13.0 */ @@ -135,8 +163,8 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T * * @return An OutputStream * @throws IOException if an I/O error occurs. - * @throws UnsupportedOperationException if the origin cannot be converted to an OututStream. - * @throws IllegalStateException if the {@code origin} is {@code null}. + * @throws UnsupportedOperationException if the origin cannot be converted to an OutputStream. + * @throws IllegalStateException if the {@code origin} is {@code null}. * @see AbstractOrigin#getOutputStream(OpenOption...) * @since 2.13.0 */ @@ -149,7 +177,7 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T * * @return A Path * @throws UnsupportedOperationException if the origin cannot be converted to a Path. - * @throws IllegalStateException if the {@code origin} is {@code null}. + * @throws IllegalStateException if the {@code origin} is {@code null}. * @see AbstractOrigin#getPath() * @since 2.13.0 */ @@ -163,7 +191,7 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T * @return An writer. * @throws IOException if an I/O error occurs. * @throws UnsupportedOperationException if the origin cannot be converted to a Writer. - * @throws IllegalStateException if the {@code origin} is {@code null}. + * @throws IllegalStateException if the {@code origin} is {@code null}. * @see AbstractOrigin#getOutputStream(OpenOption...) * @since 2.13.0 */ @@ -181,7 +209,7 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T * @return this. */ public B setBufferSize(final int bufferSize) { - this.bufferSize = bufferSize > 0 ? bufferSize : bufferSizeDefault; + this.bufferSize = checkBufferSize(bufferSize > 0 ? bufferSize : bufferSizeDefault); return asThis(); } @@ -200,6 +228,18 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T } /** + * Sets the buffer size checker function. Throws a {@link IllegalArgumentException} by default. + * + * @param bufferSizeChecker the buffer size checker function. null resets to the default behavior. + * @return this + * @since 2.14.0 + */ + public B setBufferSizeChecker(final IntUnaryOperator bufferSizeChecker) { + this.bufferSizeChecker = bufferSizeChecker != null ? bufferSizeChecker : defaultSizeChecker; + return asThis(); + } + + /** * Sets the buffer size for subclasses to initialize. * <p> * Subclasses may ignore this setting. @@ -214,6 +254,19 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T } /** + * The maximum buffer size checked by the buffer size checker. Values less or equal to 0, resets to the int max value. By default, if this value is + * exceeded, this methods throws an {@link IllegalArgumentException}. + * + * @param bufferSizeMax maximum buffer size checked by the buffer size checker. + * @return this. + * @since 2.14.0 + */ + public B setBufferSizeMax(final int bufferSizeMax) { + this.bufferSizeMax = bufferSizeMax > 0 ? bufferSizeMax : DEFAULT_MAX_VALUE; + return asThis(); + } + + /** * Sets the Charset. * <p> * Subclasses may ignore this setting. @@ -274,4 +327,8 @@ public abstract class AbstractStreamBuilder<T, B extends AbstractStreamBuilder<T this.openOptions = openOptions != null ? openOptions : DEFAULT_OPEN_OPTIONS; return asThis(); } + + private int throwIae(final int size, final int max) { + throw new IllegalArgumentException(String.format("Request %,d exceeds maximum %,d", size, max)); + } } diff --git a/src/main/java/org/apache/commons/io/charset/package-info.java b/src/main/java/org/apache/commons/io/charset/package-info.java index 56ee6c0b..7888dcc7 100644 --- a/src/main/java/org/apache/commons/io/charset/package-info.java +++ b/src/main/java/org/apache/commons/io/charset/package-info.java @@ -17,6 +17,7 @@ /** * Provides classes to work with code from {@link java.nio.charset}. + * * @since 2.12.0 */ package org.apache.commons.io.charset; diff --git a/src/main/java/org/apache/commons/io/comparator/package-info.java b/src/main/java/org/apache/commons/io/comparator/package-info.java index 3a0926db..17f6a962 100644 --- a/src/main/java/org/apache/commons/io/comparator/package-info.java +++ b/src/main/java/org/apache/commons/io/comparator/package-info.java @@ -17,7 +17,7 @@ /** * Provides various {@link java.util.Comparator} implementations - * for {@link java.io.File}s. + * for {@link java.io.File}s and {@link java.nio.file.Path}. * <h2>Sorting</h2> * <p> * All the comparators include <i>convenience</i> utility <code>sort(File...)</code> and diff --git a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java index 0574ddd7..ecfdd2b7 100644 --- a/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/AccumulatorPathVisitor.java @@ -61,7 +61,7 @@ import org.apache.commons.io.function.IOBiFunction; public class AccumulatorPathVisitor extends CountingPathVisitor { /** - * Creates a new instance configured with a BigInteger {@link PathCounters}. + * Constructs a new instance configured with a BigInteger {@link PathCounters}. * * @return a new instance configured with a BigInteger {@link PathCounters}. */ @@ -70,7 +70,7 @@ public class AccumulatorPathVisitor extends CountingPathVisitor { } /** - * Creates a new instance configured with a BigInteger {@link PathCounters}. + * Constructs a new instance configured with a BigInteger {@link PathCounters}. * * @param fileFilter Filters files to accumulate and count. * @param dirFilter Filters directories to accumulate and count. @@ -83,7 +83,7 @@ public class AccumulatorPathVisitor extends CountingPathVisitor { } /** - * Creates a new instance configured with a long {@link PathCounters}. + * Constructs a new instance configured with a long {@link PathCounters}. * * @return a new instance configured with a long {@link PathCounters}. */ @@ -92,7 +92,7 @@ public class AccumulatorPathVisitor extends CountingPathVisitor { } /** - * Creates a new instance configured with a long {@link PathCounters}. + * Constructs a new instance configured with a long {@link PathCounters}. * * @param fileFilter Filters files to accumulate and count. * @param dirFilter Filters directories to accumulate and count. diff --git a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java index a94cf633..79162f32 100644 --- a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java @@ -36,7 +36,7 @@ import org.apache.commons.io.file.Counters.PathCounters; public class CleaningPathVisitor extends CountingPathVisitor { /** - * Creates a new instance configured with a BigInteger {@link PathCounters}. + * Constructs a new instance configured with a BigInteger {@link PathCounters}. * * @return a new instance configured with a BigInteger {@link PathCounters}. */ @@ -45,7 +45,7 @@ public class CleaningPathVisitor extends CountingPathVisitor { } /** - * Creates a new instance configured with a long {@link PathCounters}. + * Constructs a new instance configured with a long {@link PathCounters}. * * @return a new instance configured with a long {@link PathCounters}. */ diff --git a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java index b841019d..00368ef9 100644 --- a/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/CountingPathVisitor.java @@ -49,7 +49,7 @@ public class CountingPathVisitor extends SimplePathVisitor { } /** - * Creates a new instance configured with a {@link BigInteger} {@link PathCounters}. + * Constructs a new instance configured with a {@link BigInteger} {@link PathCounters}. * * @return a new instance configured with a {@link BigInteger} {@link PathCounters}. */ @@ -58,7 +58,7 @@ public class CountingPathVisitor extends SimplePathVisitor { } /** - * Creates a new instance configured with a {@code long} {@link PathCounters}. + * Constructs a new instance configured with a {@code long} {@link PathCounters}. * * @return a new instance configured with a {@code long} {@link PathCounters}. */ diff --git a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java index 0d3b5334..aff9bcd3 100644 --- a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java +++ b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java @@ -37,7 +37,7 @@ import org.apache.commons.io.file.Counters.PathCounters; public class DeletingPathVisitor extends CountingPathVisitor { /** - * Creates a new instance configured with a BigInteger {@link PathCounters}. + * Constructs a new instance configured with a BigInteger {@link PathCounters}. * * @return a new instance configured with a BigInteger {@link PathCounters}. */ @@ -46,7 +46,7 @@ public class DeletingPathVisitor extends CountingPathVisitor { } /** - * Creates a new instance configured with a long {@link PathCounters}. + * Constructs a new instance configured with a long {@link PathCounters}. * * @return a new instance configured with a long {@link PathCounters}. */ diff --git a/src/main/java/org/apache/commons/io/file/FilesUncheck.java b/src/main/java/org/apache/commons/io/file/FilesUncheck.java index e99d09cc..02a1febb 100644 --- a/src/main/java/org/apache/commons/io/file/FilesUncheck.java +++ b/src/main/java/org/apache/commons/io/file/FilesUncheck.java @@ -42,6 +42,7 @@ import java.nio.file.attribute.UserPrincipal; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiPredicate; import java.util.stream.Stream; import org.apache.commons.io.function.Uncheck; @@ -242,6 +243,22 @@ public final class FilesUncheck { } /** + * Delegates to {@link Files#find(Path, int, BiPredicate, FileVisitOption...)} throwing {@link UncheckedIOException} instead of {@link IOException}. + * + * @param start See delegate. + * @param maxDepth See delegate. + * @param matcher See delegate. + * @param options See delegate. + * @return See delegate. + * @throws UncheckedIOException Wraps an {@link IOException}. + * @since 2.14.0 + */ + public static Stream<Path> find(final Path start, final int maxDepth, final BiPredicate<Path, BasicFileAttributes> matcher, + final FileVisitOption... options) { + return Uncheck.apply(Files::find, start, maxDepth, matcher, options); + } + + /** * Delegates to {@link Files#getAttribute(Path, String, LinkOption...)} throwing {@link UncheckedIOException} instead of * {@link IOException}. * diff --git a/src/main/java/org/apache/commons/io/file/PathUtils.java b/src/main/java/org/apache/commons/io/file/PathUtils.java index 1c6bd0d6..56b2a05c 100644 --- a/src/main/java/org/apache/commons/io/file/PathUtils.java +++ b/src/main/java/org/apache/commons/io/file/PathUtils.java @@ -1646,11 +1646,11 @@ public final class PathUtils { * @param <T> See {@link Files#walkFileTree(Path,FileVisitor)}. * @return the given visitor. * + * @throws NoSuchFileException if the directory does not exist. * @throws IOException if an I/O error is thrown by a visitor method. * @throws NullPointerException if the directory is {@code null}. */ public static <T extends FileVisitor<? super Path>> T visitFileTree(final T visitor, final Path directory) throws IOException { - requireExists(directory, "directory"); Files.walkFileTree(directory, visitor); return visitor; } diff --git a/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java index 72abc5dc..2bdeab49 100644 --- a/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/IOFileFilter.java @@ -21,6 +21,7 @@ import java.io.FileFilter; import java.io.FilenameFilter; import java.nio.file.FileVisitResult; import java.nio.file.Path; +import java.nio.file.PathMatcher; import java.nio.file.attribute.BasicFileAttributes; import org.apache.commons.io.file.PathFilter; @@ -30,7 +31,7 @@ import org.apache.commons.io.file.PathFilter; * * @since 1.0 */ -public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { +public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter, PathMatcher { /** * An empty String array. @@ -38,7 +39,7 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { String[] EMPTY_STRING_ARRAY = {}; /** - * Checks to see if the File should be accepted by this filter. + * Tests if a File should be accepted by this filter. * <p> * Defined in {@link java.io.FileFilter}. * </p> @@ -50,7 +51,7 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { boolean accept(File file); /** - * Checks to see if the File should be accepted by this filter. + * Tests if a File should be accepted by this filter. * <p> * Defined in {@link java.io.FilenameFilter}. * </p> @@ -63,7 +64,7 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { boolean accept(File dir, String name); /** - * Checks to see if the Path should be accepted by this filter. + * Checks to see if a Path should be accepted by this filter. * * @param path the Path to check. * @return true if this path matches the test. @@ -71,11 +72,11 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { */ @Override default FileVisitResult accept(final Path path, final BasicFileAttributes attributes) { - return AbstractFileFilter.toDefaultFileVisitResult(accept(path.toFile())); + return AbstractFileFilter.toDefaultFileVisitResult(path != null && accept(path.toFile())); } /** - * Creates a new "and" filter with this filter. + * Constructs a new "and" filter with this filter. * * @param fileFilter the filter to "and". * @return a new filter. @@ -86,7 +87,19 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { } /** - * Creates a new "not" filter with this filter. + * Tests if a Path should be accepted by this filter. + * + * @param path the Path to check. + * @return true if this path matches the test. + * @since 2.14.0 + */ + @Override + default boolean matches(final Path path) { + return accept(path, null) != FileVisitResult.TERMINATE; + } + + /** + * Constructs a new "not" filter with this filter. * * @return a new filter. * @since 2.9.0 @@ -96,7 +109,7 @@ public interface IOFileFilter extends FileFilter, FilenameFilter, PathFilter { } /** - * Creates a new "or" filter with this filter. + * Constructs a new "or" filter with this filter. * * @param fileFilter the filter to "or". * @return a new filter. diff --git a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java index e7743408..1793ef2a 100644 --- a/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java +++ b/src/main/java/org/apache/commons/io/filefilter/MagicNumberFileFilter.java @@ -293,6 +293,7 @@ public class MagicNumberFileFilter extends AbstractFileFilter implements Seriali try { try (FileChannel fileChannel = FileChannel.open(file)) { final ByteBuffer byteBuffer = ByteBuffer.allocate(this.magicNumbers.length); + fileChannel.position(byteOffset); final int read = fileChannel.read(byteBuffer); if (read != magicNumbers.length) { return FileVisitResult.TERMINATE; diff --git a/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java b/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java new file mode 100644 index 00000000..76b73eb3 --- /dev/null +++ b/src/main/java/org/apache/commons/io/filefilter/PathMatcherFileFilter.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.filefilter; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.Objects; + +/** + * Delegates matching to a {@link PathMatcher}. + * + * @since 2.14.0 + */ +public class PathMatcherFileFilter extends AbstractFileFilter { + + private final PathMatcher pathMatcher; + + /** + * Constructs a new instance to perform matching with a PathMatcher. + * + * @param pathMatcher The PathMatcher delegate. + */ + public PathMatcherFileFilter(final PathMatcher pathMatcher) { + this.pathMatcher = Objects.requireNonNull(pathMatcher, "pathMatcher"); + } + + @Override + public boolean accept(final File file) { + return file != null && matches(file.toPath()); + } + @Override + public boolean matches(final Path path) { + return pathMatcher.matches(path); + } +} diff --git a/src/main/java/org/apache/commons/io/function/IOBaseStream.java b/src/main/java/org/apache/commons/io/function/IOBaseStream.java index 6ac9bee2..2048709e 100644 --- a/src/main/java/org/apache/commons/io/function/IOBaseStream.java +++ b/src/main/java/org/apache/commons/io/function/IOBaseStream.java @@ -34,7 +34,7 @@ import java.util.stream.Stream; public interface IOBaseStream<T, S extends IOBaseStream<T, S, B>, B extends BaseStream<T, B>> extends Closeable { /** - * Creates a {@link BaseStream} for this instance that throws {@link UncheckedIOException} instead of + * Constructs a {@link BaseStream} for this instance that throws {@link UncheckedIOException} instead of * {@link IOException}. * * @return an {@link UncheckedIOException} {@link BaseStream}. diff --git a/src/main/java/org/apache/commons/io/function/IOIntSupplier.java b/src/main/java/org/apache/commons/io/function/IOIntSupplier.java new file mode 100644 index 00000000..420498b7 --- /dev/null +++ b/src/main/java/org/apache/commons/io/function/IOIntSupplier.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.IntSupplier; +import java.util.function.Supplier; + +/** + * Like {@link IntSupplier} but throws {@link IOException}. + * + * @since 2.14.0 + */ +@FunctionalInterface +public interface IOIntSupplier { + + /** + * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}. + * + * @return an UncheckedIOException Supplier. + */ + default IntSupplier asIntSupplier() { + return () -> Uncheck.getAsInt(this); + } + + /** + * Gets a result. + * + * @return a result + * @throws IOException if an I/O error occurs. + */ + int getAsInt() throws IOException; +} diff --git a/src/main/java/org/apache/commons/io/function/IOLongSupplier.java b/src/main/java/org/apache/commons/io/function/IOLongSupplier.java new file mode 100644 index 00000000..0741654b --- /dev/null +++ b/src/main/java/org/apache/commons/io/function/IOLongSupplier.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.function.LongSupplier; +import java.util.function.Supplier; + +/** + * Like {@link LongSupplier} but throws {@link IOException}. + * + * @since 2.14.0 + */ +@FunctionalInterface +public interface IOLongSupplier { + + /** + * Creates a {@link Supplier} for this instance that throws {@link UncheckedIOException} instead of {@link IOException}. + * + * @return an UncheckedIOException Supplier. + */ + default LongSupplier asSupplier() { + return () -> Uncheck.getAsLong(this); + } + + /** + * Gets a result. + * + * @return a result + * @throws IOException if an I/O error occurs. + */ + long getAsLong() throws IOException; +} diff --git a/src/main/java/org/apache/commons/io/function/IOSpliterator.java b/src/main/java/org/apache/commons/io/function/IOSpliterator.java index e9031cd3..1e8dafa3 100644 --- a/src/main/java/org/apache/commons/io/function/IOSpliterator.java +++ b/src/main/java/org/apache/commons/io/function/IOSpliterator.java @@ -43,7 +43,7 @@ public interface IOSpliterator<T> { } /** - * Creates a {@link Spliterator} for this instance that throws {@link UncheckedIOException} instead of + * Constructs a {@link Spliterator} for this instance that throws {@link UncheckedIOException} instead of * {@link IOException}. * * @return an {@link UncheckedIOException} {@link Spliterator}. diff --git a/src/main/java/org/apache/commons/io/function/Uncheck.java b/src/main/java/org/apache/commons/io/function/Uncheck.java index e18937f8..a593b56a 100644 --- a/src/main/java/org/apache/commons/io/function/Uncheck.java +++ b/src/main/java/org/apache/commons/io/function/Uncheck.java @@ -19,6 +19,7 @@ package org.apache.commons.io.function; import java.io.IOException; import java.io.UncheckedIOException; +import java.util.function.Supplier; /** * Unchecks calls by throwing {@link UncheckedIOException} instead of {@link IOException}. @@ -200,6 +201,89 @@ public final class Uncheck { } /** + * Gets the result from an IO supplier. + * + * @param <T> the return type of the operations. + * @param supplier Supplies the return value. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + */ + public static <T> T get(final IOSupplier<T> supplier, final Supplier<String> message) { + try { + return supplier.get(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** + * Gets the result from an IO int supplier. + * + * @param supplier Supplies the return value. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static int getAsInt(final IOIntSupplier supplier) { + try { + return supplier.getAsInt(); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Gets the result from an IO int supplier. + * + * @param supplier Supplies the return value. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static int getAsInt(final IOIntSupplier supplier, final Supplier<String> message) { + try { + return supplier.getAsInt(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** + * Gets the result from an IO long supplier. + * + * @param supplier Supplies the return value. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static long getAsLong(final IOLongSupplier supplier) { + try { + return supplier.getAsLong(); + } catch (final IOException e) { + throw wrap(e); + } + } + + /** + * Gets the result from an IO long supplier. + * + * @param supplier Supplies the return value. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return result from the supplier. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static long getAsLong(final IOLongSupplier supplier, final Supplier<String> message) { + try { + return supplier.getAsLong(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** * Runs an IO runnable. * * @param runnable The runnable to run. @@ -214,6 +298,22 @@ public final class Uncheck { } /** + * Runs an IO runnable. + * + * @param runnable The runnable to run. + * @param message The UncheckedIOException message if an I/O error occurs. + * @throws UncheckedIOException if an I/O error occurs. + * @since 2.14.0 + */ + public static void run(final IORunnable runnable, final Supplier<String> message) { + try { + runnable.run(); + } catch (final IOException e) { + throw wrap(e, message); + } + } + + /** * Tests an IO predicate. * * @param <T> the type of the input to the predicate. @@ -230,10 +330,7 @@ public final class Uncheck { } /** - * Creates a new UncheckedIOException for the given detail message. - * <p> - * This method exists because there is no String constructor in {@link UncheckedIOException}. - * </p> + * Constructs a new UncheckedIOException for the given exception. * * @param e The exception to wrap. * @return a new {@link UncheckedIOException}. @@ -243,6 +340,17 @@ public final class Uncheck { } /** + * Constructs a new UncheckedIOException for the given exception and detail message. + * + * @param e The exception to wrap. + * @param message The UncheckedIOException message if an I/O error occurs. + * @return a new {@link UncheckedIOException}. + */ + private static UncheckedIOException wrap(final IOException e, final Supplier<String> message) { + return new UncheckedIOException(message.get(), e); + } + + /** * No instances needed. */ private Uncheck() { diff --git a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java index 187e59b9..7a6089d0 100644 --- a/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java +++ b/src/main/java/org/apache/commons/io/input/AutoCloseInputStream.java @@ -91,7 +91,7 @@ public class AutoCloseInputStream extends ProxyInputStream { } /** - * Creates an automatically closing proxy for the given input stream. + * Constructs an automatically closing proxy for the given input stream. * * @param in underlying input stream * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} diff --git a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java index 4d846259..5eabb977 100644 --- a/src/main/java/org/apache/commons/io/input/BrokenInputStream.java +++ b/src/main/java/org/apache/commons/io/input/BrokenInputStream.java @@ -43,14 +43,14 @@ public class BrokenInputStream extends InputStream { private final Supplier<IOException> exceptionSupplier; /** - * Creates a new stream that always throws an {@link IOException}. + * Constructs a new stream that always throws an {@link IOException}. */ public BrokenInputStream() { this(() -> new IOException("Broken input stream")); } /** - * Creates a new stream that always throws the given exception. + * Constructs a new stream that always throws the given exception. * * @param exception the exception to be thrown. */ @@ -59,7 +59,7 @@ public class BrokenInputStream extends InputStream { } /** - * Creates a new stream that always throws an {@link IOException}. + * Constructs a new stream that always throws an {@link IOException}. * * @param exceptionSupplier a supplier for the exception to be thrown. * @since 2.12.0 diff --git a/src/main/java/org/apache/commons/io/input/BrokenReader.java b/src/main/java/org/apache/commons/io/input/BrokenReader.java index 9748933f..03530e8c 100644 --- a/src/main/java/org/apache/commons/io/input/BrokenReader.java +++ b/src/main/java/org/apache/commons/io/input/BrokenReader.java @@ -43,14 +43,14 @@ public class BrokenReader extends Reader { private final Supplier<IOException> exceptionSupplier; /** - * Creates a new reader that always throws an {@link IOException}. + * Constructs a new reader that always throws an {@link IOException}. */ public BrokenReader() { this(() -> new IOException("Broken reader")); } /** - * Creates a new reader that always throws the given exception. + * Constructs a new reader that always throws the given exception. * * @param exception the exception to be thrown. */ @@ -59,7 +59,7 @@ public class BrokenReader extends Reader { } /** - * Creates a new reader that always throws an {@link IOException} + * Constructs a new reader that always throws an {@link IOException} * * @param exceptionSupplier a supplier for the exception to be thrown. * @since 2.12.0 diff --git a/src/main/java/org/apache/commons/io/input/CircularInputStream.java b/src/main/java/org/apache/commons/io/input/CircularInputStream.java index d7e04a40..26d1c3f9 100644 --- a/src/main/java/org/apache/commons/io/input/CircularInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CircularInputStream.java @@ -56,7 +56,7 @@ public class CircularInputStream extends InputStream { private final long targetByteCount; /** - * Creates an instance from the specified array of bytes. + * Constructs an instance from the specified array of bytes. * * @param repeatContent Input buffer to be repeated this buffer is not copied. * @param targetByteCount How many bytes the read. A negative number means an infinite target count. diff --git a/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java b/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java index 0fd10d53..03521d90 100644 --- a/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java +++ b/src/main/java/org/apache/commons/io/input/CloseShieldInputStream.java @@ -31,7 +31,7 @@ import java.io.InputStream; public class CloseShieldInputStream extends ProxyInputStream { /** - * Creates a proxy that shields the given input stream from being closed. + * Constructs a proxy that shields the given input stream from being closed. * * @param inputStream the input stream to wrap * @return the created proxy @@ -42,7 +42,7 @@ public class CloseShieldInputStream extends ProxyInputStream { } /** - * Creates a proxy that shields the given input stream from being closed. + * Constructs a proxy that shields the given input stream from being closed. * * @param inputStream underlying input stream * @deprecated Using this constructor prevents IDEs from warning if the diff --git a/src/main/java/org/apache/commons/io/input/CloseShieldReader.java b/src/main/java/org/apache/commons/io/input/CloseShieldReader.java index 375ae20d..585a297b 100644 --- a/src/main/java/org/apache/commons/io/input/CloseShieldReader.java +++ b/src/main/java/org/apache/commons/io/input/CloseShieldReader.java @@ -31,7 +31,7 @@ import java.io.Reader; public class CloseShieldReader extends ProxyReader { /** - * Creates a proxy that shields the given reader from being closed. + * Constructs a proxy that shields the given reader from being closed. * * @param reader the reader to wrap * @return the created proxy @@ -42,7 +42,7 @@ public class CloseShieldReader extends ProxyReader { } /** - * Creates a proxy that shields the given reader from being closed. + * Constructs a proxy that shields the given reader from being closed. * * @param reader underlying reader * @deprecated Using this constructor prevents IDEs from warning if the diff --git a/src/main/java/org/apache/commons/io/input/InfiniteCircularInputStream.java b/src/main/java/org/apache/commons/io/input/InfiniteCircularInputStream.java index 0514c7e4..630177e8 100644 --- a/src/main/java/org/apache/commons/io/input/InfiniteCircularInputStream.java +++ b/src/main/java/org/apache/commons/io/input/InfiniteCircularInputStream.java @@ -32,7 +32,7 @@ import java.io.InputStream; public class InfiniteCircularInputStream extends CircularInputStream { /** - * Creates an instance from the specified array of bytes. + * Constructs an instance from the specified array of bytes. * * @param repeatContent Input buffer to be repeated this buffer is not copied. */ diff --git a/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java b/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java index 083525b7..97653fc1 100644 --- a/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MarkShieldInputStream.java @@ -36,7 +36,7 @@ import java.io.InputStream; public class MarkShieldInputStream extends ProxyInputStream { /** - * Creates a proxy that shields the given input stream from being + * Constructs a proxy that shields the given input stream from being * marked or rest. * * @param in underlying input stream diff --git a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java index 96198aaa..7aed4185 100644 --- a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java @@ -120,7 +120,7 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream { private final MessageDigest messageDigest; /** - * Creates an MessageDigestMaintainingObserver for the given MessageDigest. + * Constructs an MessageDigestMaintainingObserver for the given MessageDigest. * * @param messageDigest the message digest to use */ @@ -171,7 +171,7 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream { private final MessageDigest messageDigest; /** - * Creates a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the "MD5" algorithm. + * Constructs a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the "MD5" algorithm. * <p> * The MD5 algorithm is weak and should not be used. * </p> @@ -186,7 +186,7 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream { } /** - * Creates a new instance, which calculates a signature on the given stream, using the given {@link MessageDigest}. + * Constructs a new instance, which calculates a signature on the given stream, using the given {@link MessageDigest}. * * @param inputStream the stream to calculate the message digest for * @param messageDigest the message digest to use @@ -199,7 +199,7 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream { } /** - * Creates a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the given algorithm. + * Constructs a new instance, which calculates a signature on the given stream, using a {@link MessageDigest} with the given algorithm. * * @param inputStream the stream to calculate the message digest for * @param algorithm the name of the algorithm requested. See the MessageDigest section in the diff --git a/src/main/java/org/apache/commons/io/input/NullReader.java b/src/main/java/org/apache/commons/io/input/NullReader.java index 194d16fd..ba221e04 100644 --- a/src/main/java/org/apache/commons/io/input/NullReader.java +++ b/src/main/java/org/apache/commons/io/input/NullReader.java @@ -82,7 +82,7 @@ public class NullReader extends Reader { private final boolean markSupported; /** - * Creates a {@link Reader} that emulates a size 0 reader + * Constructs a {@link Reader} that emulates a size 0 reader * which supports marking and does not throw EOFException. * * @since 2.7 @@ -92,7 +92,7 @@ public class NullReader extends Reader { } /** - * Creates a {@link Reader} that emulates a specified size + * Constructs a {@link Reader} that emulates a specified size * which supports marking and does not throw EOFException. * * @param size The size of the reader to emulate. @@ -102,7 +102,7 @@ public class NullReader extends Reader { } /** - * Creates a {@link Reader} that emulates a specified + * Constructs a {@link Reader} that emulates a specified * size with option settings. * * @param size The size of the reader to emulate. diff --git a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java index 259f64c9..ee080f06 100644 --- a/src/main/java/org/apache/commons/io/input/ObservableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ObservableInputStream.java @@ -110,7 +110,7 @@ public class ObservableInputStream extends ProxyInputStream { private final List<Observer> observers; /** - * Creates a new ObservableInputStream for the given InputStream. + * Constructs a new ObservableInputStream for the given InputStream. * * @param inputStream the input stream to observe. */ @@ -119,7 +119,7 @@ public class ObservableInputStream extends ProxyInputStream { } /** - * Creates a new ObservableInputStream for the given InputStream. + * Constructs a new ObservableInputStream for the given InputStream. * * @param inputStream the input stream to observe. * @param observers List of observer callbacks. @@ -130,7 +130,7 @@ public class ObservableInputStream extends ProxyInputStream { } /** - * Creates a new ObservableInputStream for the given InputStream. + * Constructs a new ObservableInputStream for the given InputStream. * * @param inputStream the input stream to observe. * @param observers List of observer callbacks. diff --git a/src/main/java/org/apache/commons/io/input/QueueInputStream.java b/src/main/java/org/apache/commons/io/input/QueueInputStream.java index 5956fcf9..1ed2e84a 100644 --- a/src/main/java/org/apache/commons/io/input/QueueInputStream.java +++ b/src/main/java/org/apache/commons/io/input/QueueInputStream.java @@ -183,7 +183,7 @@ public class QueueInputStream extends InputStream { } /** - * Creates a new QueueOutputStream instance connected to this. Writes to the output stream will be visible to this input stream. + * Constructs a new QueueOutputStream instance connected to this. Writes to the output stream will be visible to this input stream. * * @return QueueOutputStream connected to this stream. */ @@ -204,7 +204,7 @@ public class QueueInputStream extends InputStream { return value == null ? EOF : 0xFF & value; } catch (final InterruptedException e) { Thread.currentThread().interrupt(); - // throw runtime unchecked exception to maintain signature backward-compatibilty of + // throw runtime unchecked exception to maintain signature backward-compatibility of // this read method, which does not declare IOException throw new IllegalStateException(e); } diff --git a/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java b/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java index 02218696..647ee4d1 100644 --- a/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java +++ b/src/main/java/org/apache/commons/io/input/RandomAccessFileInputStream.java @@ -211,17 +211,6 @@ public class RandomAccessFileInputStream extends InputStream { return randomAccessFile.read(bytes, offset, length); } - /** - * Delegates to the underlying file. - * - * @param position See {@link RandomAccessFile#seek(long)}. - * @throws IOException See {@link RandomAccessFile#seek(long)}. - * @see RandomAccessFile#seek(long) - */ - private void seek(final long position) throws IOException { - randomAccessFile.seek(position); - } - @Override public long skip(final long skipCount) throws IOException { if (skipCount <= 0) { @@ -235,7 +224,7 @@ public class RandomAccessFileInputStream extends InputStream { final long targetPos = filePointer + skipCount; final long newPos = targetPos > fileLength ? fileLength - 1 : targetPos; if (newPos > 0) { - seek(newPos); + randomAccessFile.seek(newPos); } return randomAccessFile.getFilePointer() - filePointer; } diff --git a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java index 02b79a03..dc4fc08d 100644 --- a/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java @@ -113,7 +113,7 @@ public class ReadAheadInputStream extends FilterInputStream { } /** - * Creates a new daemon thread. + * Constructs a new daemon thread. * * @param r the thread's runnable. * @return a new daemon thread. @@ -125,7 +125,7 @@ public class ReadAheadInputStream extends FilterInputStream { } /** - * Creates a new daemon executor service. + * Constructs a new daemon executor service. * * @return a new daemon executor service. */ @@ -178,7 +178,7 @@ public class ReadAheadInputStream extends FilterInputStream { private final Condition asyncReadComplete = stateChangeLock.newCondition(); /** - * Creates an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. @@ -190,7 +190,7 @@ public class ReadAheadInputStream extends FilterInputStream { } /** - * Creates an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. @@ -203,7 +203,7 @@ public class ReadAheadInputStream extends FilterInputStream { } /** - * Creates an instance with the specified buffer size and read-ahead threshold + * Constructs an instance with the specified buffer size and read-ahead threshold * * @param inputStream The underlying input stream. * @param bufferSizeInBytes The buffer size. diff --git a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java index 0933079e..cfe79fc1 100644 --- a/src/main/java/org/apache/commons/io/input/ReaderInputStream.java +++ b/src/main/java/org/apache/commons/io/input/ReaderInputStream.java @@ -148,14 +148,6 @@ public class ReaderInputStream extends InputStream { } - private static CharsetEncoder newEncoder(final Charset charset) { - // @formatter:off - return Charsets.toCharset(charset).newEncoder() - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE); - // @formatter:on - } - /** * Constructs a new {@link Builder}. * @@ -179,6 +171,14 @@ public class ReaderInputStream extends InputStream { return charsetEncoder.maxBytesPerChar() * 2; } + private static CharsetEncoder newEncoder(final Charset charset) { + // @formatter:off + return Charsets.toCharset(charset).newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); + // @formatter:on + } + private final Reader reader; private final CharsetEncoder charsetEncoder; @@ -339,6 +339,9 @@ public class ReaderInputStream extends InputStream { * @throws IOException If an I/O error occurs */ private void fillBuffer() throws IOException { + if (endOfInput) { + return; + } if (!endOfInput && (lastCoderResult == null || lastCoderResult.isUnderflow())) { encoderIn.compact(); final int position = encoderIn.position(); diff --git a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java index ef5fdf13..04c9cf91 100644 --- a/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +++ b/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java @@ -132,7 +132,7 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates the buffer containing any leftover bytes. + * Constructs the buffer containing any leftover bytes. */ private void createLeftOver() { final int lineLengthBytes = currentLastBytePos + 1; @@ -275,12 +275,12 @@ public class ReversedLinesFileReader implements Closeable { private boolean trailingNewlineOfFileSkipped; /** - * Creates a ReversedLinesFileReader with default block size of 4KB and the + * Constructs a ReversedLinesFileReader with default block size of 4KB and the * platform's default encoding. * * @param file the file to be read * @throws IOException if an I/O error occurs. - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final File file) throws IOException { @@ -288,14 +288,14 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with default block size of 4KB and the + * Constructs a ReversedLinesFileReader with default block size of 4KB and the * specified encoding. * * @param file the file to be read * @param charset the charset to use, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.5 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final File file, final Charset charset) throws IOException { @@ -303,7 +303,7 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with the given block size and encoding. + * Constructs a ReversedLinesFileReader with the given block size and encoding. * * @param file the file to be read * @param blockSize size of the internal buffer (for ideal performance this @@ -312,7 +312,7 @@ public class ReversedLinesFileReader implements Closeable { * @param charset the encoding of the file, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.3 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final File file, final int blockSize, final Charset charset) throws IOException { @@ -320,7 +320,7 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with the given block size and encoding. + * Constructs a ReversedLinesFileReader with the given block size and encoding. * * @param file the file to be read * @param blockSize size of the internal buffer (for ideal performance this @@ -333,7 +333,7 @@ public class ReversedLinesFileReader implements Closeable { * in version 2.2 if the * encoding is not * supported. - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final File file, final int blockSize, final String charsetName) throws IOException { @@ -341,14 +341,14 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with default block size of 4KB and the + * Constructs a ReversedLinesFileReader with default block size of 4KB and the * specified encoding. * * @param file the file to be read * @param charset the charset to use, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.7 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final Path file, final Charset charset) throws IOException { @@ -356,7 +356,7 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with the given block size and encoding. + * Constructs a ReversedLinesFileReader with the given block size and encoding. * * @param file the file to be read * @param blockSize size of the internal buffer (for ideal performance this @@ -365,7 +365,7 @@ public class ReversedLinesFileReader implements Closeable { * @param charset the encoding of the file, null uses the default Charset. * @throws IOException if an I/O error occurs. * @since 2.7 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final Path file, final int blockSize, final Charset charset) throws IOException { @@ -425,7 +425,7 @@ public class ReversedLinesFileReader implements Closeable { } /** - * Creates a ReversedLinesFileReader with the given block size and encoding. + * Constructs a ReversedLinesFileReader with the given block size and encoding. * * @param file the file to be read * @param blockSize size of the internal buffer (for ideal performance this @@ -439,7 +439,7 @@ public class ReversedLinesFileReader implements Closeable { * encoding is not * supported. * @since 2.7 - * @deprecated Use {@link ReaderInputStream#builder()} instead + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} */ @Deprecated public ReversedLinesFileReader(final Path file, final int blockSize, final String charsetName) throws IOException { diff --git a/src/main/java/org/apache/commons/io/input/SequenceReader.java b/src/main/java/org/apache/commons/io/input/SequenceReader.java index 514569d7..fc718bd6 100644 --- a/src/main/java/org/apache/commons/io/input/SequenceReader.java +++ b/src/main/java/org/apache/commons/io/input/SequenceReader.java @@ -21,11 +21,12 @@ import static org.apache.commons.io.IOUtils.EOF; import java.io.IOException; import java.io.Reader; import java.io.SequenceInputStream; -import java.io.UncheckedIOException; import java.util.Arrays; import java.util.Iterator; import java.util.Objects; +import org.apache.commons.io.function.Uncheck; + /** * Provides the contents of multiple {@link Reader}s in sequence. * <p> @@ -46,11 +47,7 @@ public class SequenceReader extends Reader { */ public SequenceReader(final Iterable<? extends Reader> readers) { this.readers = Objects.requireNonNull(readers, "readers").iterator(); - try { - this.reader = nextReader(); - } catch (final IOException e) { - throw new UncheckedIOException(e); - } + this.reader = Uncheck.get(this::nextReader); } /** diff --git a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java index 6134046e..b42d44c2 100644 --- a/src/main/java/org/apache/commons/io/input/TaggedInputStream.java +++ b/src/main/java/org/apache/commons/io/input/TaggedInputStream.java @@ -74,7 +74,7 @@ public class TaggedInputStream extends ProxyInputStream { private final Serializable tag = UUID.randomUUID(); /** - * Creates a tagging decorator for the given input stream. + * Constructs a tagging decorator for the given input stream. * * @param proxy input stream to be decorated */ diff --git a/src/main/java/org/apache/commons/io/input/TaggedReader.java b/src/main/java/org/apache/commons/io/input/TaggedReader.java index 8d74b60e..dc0d57fa 100644 --- a/src/main/java/org/apache/commons/io/input/TaggedReader.java +++ b/src/main/java/org/apache/commons/io/input/TaggedReader.java @@ -73,7 +73,7 @@ public class TaggedReader extends ProxyReader { private final Serializable tag = UUID.randomUUID(); /** - * Creates a tagging decorator for the given reader. + * Constructs a tagging decorator for the given reader. * * @param proxy reader to be decorated */ diff --git a/src/main/java/org/apache/commons/io/input/TeeInputStream.java b/src/main/java/org/apache/commons/io/input/TeeInputStream.java index ae1abffb..806dec72 100644 --- a/src/main/java/org/apache/commons/io/input/TeeInputStream.java +++ b/src/main/java/org/apache/commons/io/input/TeeInputStream.java @@ -51,7 +51,7 @@ public class TeeInputStream extends ProxyInputStream { private final boolean closeBranch; /** - * Creates a TeeInputStream that proxies the given {@link InputStream} + * Constructs a TeeInputStream that proxies the given {@link InputStream} * and copies all read bytes to the given {@link OutputStream}. The given * output stream will not be closed when this stream gets closed. * @@ -63,7 +63,7 @@ public class TeeInputStream extends ProxyInputStream { } /** - * Creates a TeeInputStream that proxies the given {@link InputStream} + * Constructs a TeeInputStream that proxies the given {@link InputStream} * and copies all read bytes to the given {@link OutputStream}. The given * output stream will be closed when this stream gets closed if the * closeBranch parameter is {@code true}. diff --git a/src/main/java/org/apache/commons/io/input/TeeReader.java b/src/main/java/org/apache/commons/io/input/TeeReader.java index 354cac9f..d857f7b8 100644 --- a/src/main/java/org/apache/commons/io/input/TeeReader.java +++ b/src/main/java/org/apache/commons/io/input/TeeReader.java @@ -47,7 +47,7 @@ public class TeeReader extends ProxyReader { private final boolean closeBranch; /** - * Creates a TeeReader that proxies the given {@link Reader} and copies all read characters to the given + * Constructs a TeeReader that proxies the given {@link Reader} and copies all read characters to the given * {@link Writer}. The given writer will not be closed when this reader gets closed. * * @param input reader to be proxied @@ -58,7 +58,7 @@ public class TeeReader extends ProxyReader { } /** - * Creates a TeeReader that proxies the given {@link Reader} and copies all read characters to the given + * Constructs a TeeReader that proxies the given {@link Reader} and copies all read characters to the given * {@link Writer}. The given writer will be closed when this reader gets closed if the closeBranch parameter is * {@code true}. * diff --git a/src/main/java/org/apache/commons/io/input/TimestampedObserver.java b/src/main/java/org/apache/commons/io/input/TimestampedObserver.java index df18a6cf..c331c86c 100644 --- a/src/main/java/org/apache/commons/io/input/TimestampedObserver.java +++ b/src/main/java/org/apache/commons/io/input/TimestampedObserver.java @@ -30,12 +30,12 @@ import org.apache.commons.io.input.ObservableInputStream.Observer; * </p> * * <pre> - * final TimestampedObserver timetampedObserver = new TimestampedObserver(); + * final TimestampedObserver timestampedObserver = new TimestampedObserver(); * try (ObservableInputStream inputStream = new ObservableInputStream(...), - * timetampedObserver)) { + * timestampedObserver)) { * ... * } - * System.out.printf("IO duration: %s%n", timetampedObserver.getOpenToCloseDuration()); + * System.out.printf("IO duration: %s%n", timestampedObserver.getOpenToCloseDuration()); * </pre> * * @since 2.9.0 diff --git a/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java b/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java index 1a49c9bb..c0cd7c5a 100644 --- a/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java +++ b/src/main/java/org/apache/commons/io/input/UncheckedBufferedReader.java @@ -99,7 +99,7 @@ public final class UncheckedBufferedReader extends BufferedReader { } /** - * Creates a buffering character-input stream that uses an input buffer of the specified size. + * Constructs a buffering character-input stream that uses an input buffer of the specified size. * * @param reader A Reader * @param bufferSize Input-buffer size diff --git a/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java b/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java index 58609c10..d1b00c2b 100644 --- a/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UncheckedFilterInputStream.java @@ -92,7 +92,7 @@ public final class UncheckedFilterInputStream extends FilterInputStream { } /** - * Creates a {@link UncheckedFilterInputStream}. + * Constructs a {@link UncheckedFilterInputStream}. * * @param inputStream the underlying input stream, or {@code null} if this instance is to be created without an * underlying stream. diff --git a/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java b/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java index 768a16b7..4b9fe8e1 100644 --- a/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java +++ b/src/main/java/org/apache/commons/io/input/UncheckedFilterReader.java @@ -95,7 +95,7 @@ public final class UncheckedFilterReader extends FilterReader { } /** - * Creates a new filtered reader. + * Constructs a new filtered reader. * * @param reader a Reader object providing the underlying stream. * @throws NullPointerException if {@code reader} is {@code null}. diff --git a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java index 175776f5..7b0ebb22 100644 --- a/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java @@ -41,7 +41,7 @@ public class UnixLineEndingInputStream extends InputStream { private final boolean lineFeedAtEndOfFile; /** - * Creates an input stream that filters another stream + * Constructs an input stream that filters another stream * * @param inputStream The input stream to wrap * @param ensureLineFeedAtEndOfFile true to ensure that the file ends with LF diff --git a/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java b/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java index 9799e99e..f8507523 100644 --- a/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java +++ b/src/main/java/org/apache/commons/io/input/UnsupportedOperationExceptions.java @@ -29,7 +29,7 @@ class UnsupportedOperationExceptions { private static final String MARK_RESET = "mark/reset"; /** - * Creates a new instance of UnsupportedOperationException for a {@code mark} method. + * Constructs a new instance of UnsupportedOperationException for a {@code mark} method. * * @return a new instance of UnsupportedOperationException */ @@ -39,7 +39,7 @@ class UnsupportedOperationExceptions { } /** - * Creates a new instance of UnsupportedOperationException for the given unsupported a {@code method} name. + * Constructs a new instance of UnsupportedOperationException for the given unsupported a {@code method} name. * * @param method A method name * @return a new instance of UnsupportedOperationException @@ -49,7 +49,7 @@ class UnsupportedOperationExceptions { } /** - * Creates a new instance of UnsupportedOperationException for a {@code reset} method. + * Constructs a new instance of UnsupportedOperationException for a {@code reset} method. * * @return a new instance of UnsupportedOperationException */ diff --git a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java index a3f489b2..a4fc696c 100644 --- a/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java +++ b/src/main/java/org/apache/commons/io/input/UnsynchronizedByteArrayInputStream.java @@ -161,7 +161,7 @@ public class UnsynchronizedByteArrayInputStream extends InputStream { private int markedOffset; /** - * Creates a new byte array input stream. + * Constructs a new byte array input stream. * * @param data the buffer * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. @@ -175,7 +175,7 @@ public class UnsynchronizedByteArrayInputStream extends InputStream { } /** - * Creates a new byte array input stream. + * Constructs a new byte array input stream. * * @param data the buffer * @param offset the offset into the buffer @@ -196,7 +196,7 @@ public class UnsynchronizedByteArrayInputStream extends InputStream { } /** - * Creates a new byte array input stream. + * Constructs a new byte array input stream. * * @param data the buffer * @param offset the offset into the buffer diff --git a/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java b/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java index ee908e1d..e5ba818d 100644 --- a/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java @@ -43,7 +43,7 @@ public class WindowsLineEndingInputStream extends InputStream { private final boolean lineFeedAtEndOfFile; /** - * Creates an input stream that filters another stream + * Constructs an input stream that filters another stream * * @param in The input stream to wrap * @param ensureLineFeedAtEndOfFile true to ensure that the file ends with CRLF diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java index 1e0c2f4a..a38ef807 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java @@ -201,14 +201,23 @@ public class XmlStreamReader extends Reader { /** * Pattern capturing the encoding of the "xml" processing instruction. + * <p> + * See also the <a href="https://www.w3.org/TR/2008/REC-xml-20081126/#NT-EncName">XML specification</a>. + * </p> */ - public static final Pattern ENCODING_PATTERN = Pattern.compile("<\\?xml.*encoding[\\s]*=[\\s]*((?:\".[^\"]*\")|(?:'.[^']*'))", Pattern.MULTILINE); + public static final Pattern ENCODING_PATTERN = Pattern.compile( + // @formatter:off + "^<\\?xml\\s+" + + "version\\s*=\\s*(?:(?:\"1\\.[0-9]+\")|(?:'1.[0-9]+'))\\s+" + + "encoding\\s*=\\s*((?:\"[A-Za-z]([A-Za-z0-9\\._]|-)*\")|(?:'[A-Za-z]([A-Za-z0-9\\\\._]|-)*'))", + Pattern.MULTILINE); + // @formatter:on private static final String RAW_EX_1 = "Illegal encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] encoding mismatch"; private static final String RAW_EX_2 = "Illegal encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM"; - private static final String HTTP_EX_1 = "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be NULL"; + private static final String HTTP_EX_1 = "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be null"; private static final String HTTP_EX_2 = "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], encoding mismatch"; @@ -225,7 +234,7 @@ public class XmlStreamReader extends Reader { } /** - * Gets the charset parameter value, NULL if not present, NULL if httpContentType is NULL. + * Gets the charset parameter value, {@code null} if not present, {@code null} if httpContentType is {@code null}. * * @param httpContentType the HTTP content type * @return The content type encoding (upcased) @@ -245,7 +254,7 @@ public class XmlStreamReader extends Reader { } /** - * Gets the MIME type or NULL if httpContentType is NULL. + * Gets the MIME type or {@code null} if httpContentType is {@code null}. * * @param httpContentType the HTTP content type * @return The mime content type @@ -265,7 +274,7 @@ public class XmlStreamReader extends Reader { } /** - * Gets the encoding declared in the <?xml encoding=...?>, NULL if none. + * Gets the encoding declared in the <?xml encoding=...?>, {@code null} if none. * * @param inputStream InputStream to create the reader from. * @param guessedEnc guessed encoding @@ -855,7 +864,7 @@ public class XmlStreamReader extends Reader { /** * Gets the default encoding to use if none is set in HTTP content-type, XML prolog and the rules based on content-type are not adequate. * <p> - * If it is NULL the content-type based rules are used. + * If it is {@code null} the content-type based rules are used. * </p> * * @return the default encoding to use. diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java b/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java index 75703298..1402a748 100644 --- a/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java +++ b/src/main/java/org/apache/commons/io/input/XmlStreamReaderException.java @@ -46,7 +46,7 @@ public class XmlStreamReaderException extends IOException { private final String contentTypeEncoding; /** - * Creates an exception instance if the charset encoding could not be + * Constructs an exception instance if the charset encoding could not be * determined. * <p> * Instances of this exception are thrown by the XmlStreamReader. @@ -63,7 +63,7 @@ public class XmlStreamReaderException extends IOException { } /** - * Creates an exception instance if the charset encoding could not be + * Constructs an exception instance if the charset encoding could not be * determined. * <p> * Instances of this exception are thrown by the XmlStreamReader. diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java index 3ac9ae12..2432cd54 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java @@ -41,7 +41,7 @@ public class CircularBufferInputStream extends FilterInputStream { private boolean eof; /** - * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size + * Constructs a new instance, which filters the given input stream, and uses a reasonable default buffer size * ({@link IOUtils#DEFAULT_BUFFER_SIZE}). * * @param inputStream The input stream, which is being buffered. @@ -51,7 +51,7 @@ public class CircularBufferInputStream extends FilterInputStream { } /** - * Creates a new instance, which filters the given input stream, and uses the given buffer size. + * Constructs a new instance, which filters the given input stream, and uses the given buffer size. * * @param inputStream The input stream, which is being buffered. * @param bufferSize The size of the {@link CircularByteBuffer}, which is used internally. diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java index b65992a3..f8e6dd3d 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java @@ -34,14 +34,14 @@ public class CircularByteBuffer { private int currentNumberOfBytes; /** - * Creates a new instance with a reasonable default buffer size ({@link IOUtils#DEFAULT_BUFFER_SIZE}). + * Constructs a new instance with a reasonable default buffer size ({@link IOUtils#DEFAULT_BUFFER_SIZE}). */ public CircularByteBuffer() { this(IOUtils.DEFAULT_BUFFER_SIZE); } /** - * Creates a new instance with the given buffer size. + * Constructs a new instance with the given buffer size. * * @param size the size of buffer to create */ diff --git a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java index a2c55f81..086ac9d2 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java @@ -29,7 +29,7 @@ import org.apache.commons.io.IOUtils; public class PeekableInputStream extends CircularBufferInputStream { /** - * Creates a new instance, which filters the given input stream, and uses a reasonable default buffer size ({@link IOUtils#DEFAULT_BUFFER_SIZE}). + * Constructs a new instance, which filters the given input stream, and uses a reasonable default buffer size ({@link IOUtils#DEFAULT_BUFFER_SIZE}). * * @param inputStream The input stream, which is being buffered. */ @@ -38,7 +38,7 @@ public class PeekableInputStream extends CircularBufferInputStream { } /** - * Creates a new instance, which filters the given input stream, and uses the given buffer size. + * Constructs a new instance, which filters the given input stream, and uses the given buffer size. * * @param inputStream The input stream, which is being buffered. * @param bufferSize The size of the {@link CircularByteBuffer}, which is used internally. diff --git a/src/main/java/org/apache/commons/io/monitor/FileEntry.java b/src/main/java/org/apache/commons/io/monitor/FileEntry.java index 63964e95..837f2df5 100644 --- a/src/main/java/org/apache/commons/io/monitor/FileEntry.java +++ b/src/main/java/org/apache/commons/io/monitor/FileEntry.java @@ -183,7 +183,7 @@ public class FileEntry implements Serializable { } /** - * Creates a new child instance. + * Constructs a new child instance. * <p> * Custom implementations should override this method to return * a new instance of the appropriate type. diff --git a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java index 59d655a4..4accc56d 100644 --- a/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/BrokenOutputStream.java @@ -45,14 +45,14 @@ public class BrokenOutputStream extends OutputStream { private final Supplier<IOException> exceptionSupplier; /** - * Creates a new stream that always throws an {@link IOException}. + * Constructs a new stream that always throws an {@link IOException}. */ public BrokenOutputStream() { this(() -> new IOException("Broken output stream")); } /** - * Creates a new stream that always throws the given exception. + * Constructs a new stream that always throws the given exception. * * @param exception the exception to be thrown. */ @@ -61,7 +61,7 @@ public class BrokenOutputStream extends OutputStream { } /** - * Creates a new stream that always throws an {@link IOException}. + * Constructs a new stream that always throws an {@link IOException}. * * @param exceptionSupplier a supplier for the exception to be thrown. * @since 2.12.0 diff --git a/src/main/java/org/apache/commons/io/output/BrokenWriter.java b/src/main/java/org/apache/commons/io/output/BrokenWriter.java index 9755a537..c56d9a31 100644 --- a/src/main/java/org/apache/commons/io/output/BrokenWriter.java +++ b/src/main/java/org/apache/commons/io/output/BrokenWriter.java @@ -43,14 +43,14 @@ public class BrokenWriter extends Writer { private final Supplier<IOException> exceptionSupplier; /** - * Creates a new writer that always throws an {@link IOException}. + * Constructs a new writer that always throws an {@link IOException}. */ public BrokenWriter() { this(() -> new IOException("Broken writer")); } /** - * Creates a new writer that always throws the given exception. + * Constructs a new writer that always throws the given exception. * * @param exception the exception to be thrown. */ @@ -59,7 +59,7 @@ public class BrokenWriter extends Writer { } /** - * Creates a new writer that always throws an {@link IOException}. + * Constructs a new writer that always throws an {@link IOException}. * * @param exceptionSupplier a supplier for the exception to be thrown. * @since 2.12.0 diff --git a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java index 23474f9f..b2b310ab 100644 --- a/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ByteArrayOutputStream.java @@ -86,7 +86,7 @@ public class ByteArrayOutputStream extends AbstractByteArrayOutputStream { } /** - * Creates a new byte array output stream. The buffer capacity is + * Constructs a new byte array output stream. The buffer capacity is * initially {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary. */ public ByteArrayOutputStream() { @@ -94,7 +94,7 @@ public class ByteArrayOutputStream extends AbstractByteArrayOutputStream { } /** - * Creates a new byte array output stream, with a buffer capacity of + * Constructs a new byte array output stream, with a buffer capacity of * the specified size, in bytes. * * @param size the initial size diff --git a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java index 396fd360..b8e2abe2 100644 --- a/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ChunkedOutputStream.java @@ -68,7 +68,7 @@ public class ChunkedOutputStream extends FilterOutputStream { * * @return a new instance. * @throws IOException if an I/O error occurs. - * @throws UnsupportedOperationException if the origin cannot be converted to an OututStream. + * @throws UnsupportedOperationException if the origin cannot be converted to an OutputStream. * @see #getOutputStream() */ @Override @@ -94,7 +94,7 @@ public class ChunkedOutputStream extends FilterOutputStream { private final int chunkSize; /** - * Creates a new stream that uses a chunk size of {@link IOUtils#DEFAULT_BUFFER_SIZE}. + * Constructs a new stream that uses a chunk size of {@link IOUtils#DEFAULT_BUFFER_SIZE}. * * @param stream the stream to wrap * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()} @@ -105,7 +105,7 @@ public class ChunkedOutputStream extends FilterOutputStream { } /** - * Creates a new stream that uses the specified chunk size. + * Constructs a new stream that uses the specified chunk size. * * @param stream the stream to wrap * @param chunkSize the chunk size to use; must be a positive number. diff --git a/src/main/java/org/apache/commons/io/output/ChunkedWriter.java b/src/main/java/org/apache/commons/io/output/ChunkedWriter.java index 37930ac1..417f19e6 100644 --- a/src/main/java/org/apache/commons/io/output/ChunkedWriter.java +++ b/src/main/java/org/apache/commons/io/output/ChunkedWriter.java @@ -42,7 +42,7 @@ public class ChunkedWriter extends FilterWriter { private final int chunkSize; /** - * Creates a new writer that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE} + * Constructs a new writer that uses a chunk size of {@link #DEFAULT_CHUNK_SIZE} * @param writer the writer to wrap */ public ChunkedWriter(final Writer writer) { @@ -50,7 +50,7 @@ public class ChunkedWriter extends FilterWriter { } /** - * Creates a new writer that uses the specified chunk size. + * Constructs a new writer that uses the specified chunk size. * * @param writer the writer to wrap * @param chunkSize the chunk size to use; must be a positive number. @@ -65,7 +65,8 @@ public class ChunkedWriter extends FilterWriter { } /** - * writes the data buffer in chunks to the underlying writer + * Writes the data buffer in chunks to the underlying writer. + * * @param data The data * @param srcOffset the offset * @param length the number of bytes to write diff --git a/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java b/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java index a5c5485d..28ff2897 100644 --- a/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/CloseShieldOutputStream.java @@ -31,7 +31,7 @@ import java.io.OutputStream; public class CloseShieldOutputStream extends ProxyOutputStream { /** - * Creates a proxy that shields the given output stream from being closed. + * Constructs a proxy that shields the given output stream from being closed. * * @param outputStream the output stream to wrap * @return the created proxy @@ -42,7 +42,7 @@ public class CloseShieldOutputStream extends ProxyOutputStream { } /** - * Creates a proxy that shields the given output stream from being closed. + * Constructs a proxy that shields the given output stream from being closed. * * @param outputStream underlying output stream * @deprecated Using this constructor prevents IDEs from warning if the diff --git a/src/main/java/org/apache/commons/io/output/CloseShieldWriter.java b/src/main/java/org/apache/commons/io/output/CloseShieldWriter.java index 8d741acf..f481b752 100644 --- a/src/main/java/org/apache/commons/io/output/CloseShieldWriter.java +++ b/src/main/java/org/apache/commons/io/output/CloseShieldWriter.java @@ -31,7 +31,7 @@ import java.io.Writer; public class CloseShieldWriter extends ProxyWriter { /** - * Creates a proxy that shields the given writer from being closed. + * Constructs a proxy that shields the given writer from being closed. * * @param writer the writer to wrap * @return the created proxy @@ -42,7 +42,7 @@ public class CloseShieldWriter extends ProxyWriter { } /** - * Creates a proxy that shields the given writer from being closed. + * Constructs a proxy that shields the given writer from being closed. * * @param writer underlying writer * @deprecated Using this constructor prevents IDEs from warning if the diff --git a/src/main/java/org/apache/commons/io/output/CountingOutputStream.java b/src/main/java/org/apache/commons/io/output/CountingOutputStream.java index c73acb60..5be3721e 100644 --- a/src/main/java/org/apache/commons/io/output/CountingOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/CountingOutputStream.java @@ -58,6 +58,7 @@ public class CountingOutputStream extends ProxyOutputStream { * NOTE: This method is an alternative for {@code getCount()}. * It was added because that method returns an integer which will * result in incorrect count for files over 2GB. + * </p> * * @return the number of bytes accumulated * @since 1.3 @@ -67,11 +68,12 @@ public class CountingOutputStream extends ProxyOutputStream { } /** - * The number of bytes that have passed through this stream. + * Gets the number of bytes that have passed through this stream. * <p> * NOTE: From v1.3 this method throws an ArithmeticException if the * count is greater than can be expressed by an {@code int}. * See {@link #getByteCount()} for a method using a {@code long}. + * </p> * * @return the number of bytes accumulated * @throws ArithmeticException if the byte count is too large @@ -90,6 +92,7 @@ public class CountingOutputStream extends ProxyOutputStream { * NOTE: This method is an alternative for {@code resetCount()}. * It was added because that method returns an integer which will * result in incorrect count for files over 2GB. + * </p> * * @return the count previous to resetting * @since 1.3 @@ -106,6 +109,7 @@ public class CountingOutputStream extends ProxyOutputStream { * NOTE: From v1.3 this method throws an ArithmeticException if the * count is greater than can be expressed by an {@code int}. * See {@link #resetByteCount()} for a method using a {@code long}. + * </p> * * @return the count previous to resetting * @throws ArithmeticException if the byte count is too large diff --git a/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java b/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java index 78bc4b9c..d4dc19e9 100644 --- a/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/DeferredFileOutputStream.java @@ -48,7 +48,6 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { * </p> * <pre>{@code * DeferredFileOutputStream s = DeferredFileOutputStream.builder() - * .setPath(path) * .setBufferSize(4096) * .setDirectory(dir) * .setOutputFile(outputFile) @@ -57,15 +56,19 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { * .setThreshold(threshold) * .get();} * </pre> + * <p> + * The only super's aspect used us buffer size. + * </p> + * * @since 2.12.0 */ public static class Builder extends AbstractStreamBuilder<DeferredFileOutputStream, Builder> { private int threshold; - private File outputFile; + private Path outputFile; private String prefix; private String suffix; - private File directory; + private Path directory; public Builder() { setBufferSizeDefault(AbstractByteArrayOutputStream.DEFAULT_SIZE); @@ -92,7 +95,19 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { * @return this */ public Builder setDirectory(final File directory) { - this.directory = directory; + this.directory = toPath(directory, null); + return this; + } + + /** + * Sets the temporary file directory. + * + * @param directory Temporary file directory. + * @return this + * @since 2.14.0 + */ + public Builder setDirectory(final Path directory) { + this.directory = toPath(directory, null); return this; } @@ -103,7 +118,19 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { * @return this */ public Builder setOutputFile(final File outputFile) { - this.outputFile = outputFile; + this.outputFile = toPath(outputFile, null); + return this; + } + + /** + * Sets the file to which data is saved beyond the threshold. + * + * @param outputFile The file to which data is saved beyond the threshold. + * @return this + * @since 2.14.0 + */ + public Builder setOutputFile(final Path outputFile) { + this.outputFile = toPath(outputFile, null); return this; } @@ -159,6 +186,14 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { return initialBufferSize; } + private static Path toPath(final File file, final Supplier<Path> defaultPathSupplier) { + return file != null ? file.toPath() : defaultPathSupplier == null ? null : defaultPathSupplier.get(); + } + + private static Path toPath(final Path file, final Supplier<Path> defaultPathSupplier) { + return file != null ? file : defaultPathSupplier == null ? null : defaultPathSupplier.get(); + } + /** * The output stream to which data will be written prior to the threshold being reached. */ @@ -230,6 +265,28 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { } /** + * Constructs an instance of this class which will trigger an event at the specified threshold, and save data either to a file beyond that point. + * + * @param threshold The number of bytes at which to trigger an event. + * @param outputFile The file to which data is saved beyond the threshold. + * @param prefix Prefix to use for the temporary file. + * @param suffix Suffix to use for the temporary file. + * @param directory Temporary file directory. + * @param initialBufferSize The initial size of the in memory buffer. + * @throws IllegalArgumentException if initialBufferSize < 0. + */ + private DeferredFileOutputStream(final int threshold, final Path outputFile, final String prefix, final String suffix, final Path directory, + final int initialBufferSize) { + super(threshold); + this.outputPath = toPath(outputFile, null); + this.prefix = prefix; + this.suffix = suffix; + this.directory = toPath(directory, PathUtils::getTempDirectory); + this.memoryOutputStream = new ByteArrayOutputStream(checkBufferSize(initialBufferSize)); + this.currentOutputStream = memoryOutputStream; + } + + /** * Constructs an instance of this class which will trigger an event at the specified threshold, and save data to a file beyond that point. * * @param threshold The number of bytes at which to trigger an event. @@ -297,20 +354,35 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { } /** - * Gets either the output file specified in the constructor or the temporary file created or null. + * Gets either the output File specified in the constructor or the temporary File created or null. * <p> - * If the constructor specifying the file is used then it returns that same output file, even when threshold has not been reached. + * If the constructor specifying the File is used then it returns that same output File, even when threshold has not been reached. * <p> - * If constructor specifying a temporary file prefix/suffix is used then the temporary file created once the threshold is reached is returned If the + * If constructor specifying a temporary File prefix/suffix is used then the temporary File created once the threshold is reached is returned if the * threshold was not reached then {@code null} is returned. * - * @return The file for this output stream, or {@code null} if no such file exists. + * @return The File for this output stream, or {@code null} if no such File exists. */ public File getFile() { return outputPath != null ? outputPath.toFile() : null; } /** + * Gets either the output Path specified in the constructor or the temporary Path created or null. + * <p> + * If the constructor specifying the file is used then it returns that same output Path, even when threshold has not been reached. + * <p> + * If constructor specifying a temporary Path prefix/suffix is used then the temporary Path created once the threshold is reached is returned if the + * threshold was not reached then {@code null} is returned. + * + * @return The Path for this output stream, or {@code null} if no such Path exists. + * @since 2.14.0 + */ + public Path getPath() { + return outputPath; + } + + /** * Gets the current output stream. This may be memory based or disk based, depending on the current state with respect to the threshold. * * @return The underlying output stream. @@ -379,10 +451,6 @@ public class DeferredFileOutputStream extends ThresholdingOutputStream { return Files.newInputStream(outputPath); } - private Path toPath(final File file, final Supplier<Path> defaultPathSupplier) { - return file != null ? file.toPath() : defaultPathSupplier == null ? null : defaultPathSupplier.get(); - } - /** * Writes the data from this output stream to the specified output stream, after it has been closed. * diff --git a/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java b/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java index f6c0aa8e..d8ce429d 100644 --- a/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java +++ b/src/main/java/org/apache/commons/io/output/FilterCollectionWriter.java @@ -57,7 +57,7 @@ public class FilterCollectionWriter extends Writer { protected final Collection<Writer> writers; /** - * Creates a new filtered collection writer. + * Constructs a new filtered collection writer. * * @param writers Writers to provide the underlying targets. */ @@ -66,7 +66,7 @@ public class FilterCollectionWriter extends Writer { } /** - * Creates a new filtered collection writer. + * Constructs a new filtered collection writer. * * @param writers Writers to provide the underlying targets. */ diff --git a/src/main/java/org/apache/commons/io/output/ProxyCollectionWriter.java b/src/main/java/org/apache/commons/io/output/ProxyCollectionWriter.java index 0a4c0378..008feb57 100644 --- a/src/main/java/org/apache/commons/io/output/ProxyCollectionWriter.java +++ b/src/main/java/org/apache/commons/io/output/ProxyCollectionWriter.java @@ -36,7 +36,7 @@ import org.apache.commons.io.IOUtils; public class ProxyCollectionWriter extends FilterCollectionWriter { /** - * Creates a new proxy collection writer. + * Constructs a new proxy collection writer. * * @param writers Writers object to provide the underlying targets. */ @@ -45,7 +45,7 @@ public class ProxyCollectionWriter extends FilterCollectionWriter { } /** - * Creates a new proxy collection writer. + * Constructs a new proxy collection writer. * * @param writers Writers to provide the underlying targets. */ diff --git a/src/main/java/org/apache/commons/io/output/QueueOutputStream.java b/src/main/java/org/apache/commons/io/output/QueueOutputStream.java index 4281aec3..dc2319b9 100644 --- a/src/main/java/org/apache/commons/io/output/QueueOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/QueueOutputStream.java @@ -74,7 +74,7 @@ public class QueueOutputStream extends OutputStream { } /** - * Creates a new QueueInputStream instance connected to this. Writes to this output stream will be visible to the + * Constructs a new QueueInputStream instance connected to this. Writes to this output stream will be visible to the * input stream. * * @return QueueInputStream connected to this stream diff --git a/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java b/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java index eeb23a0c..72d0ec97 100644 --- a/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/TaggedOutputStream.java @@ -70,7 +70,7 @@ public class TaggedOutputStream extends ProxyOutputStream { private final Serializable tag = UUID.randomUUID(); /** - * Creates a tagging decorator for the given output stream. + * Constructs a tagging decorator for the given output stream. * * @param proxy output stream to be decorated */ diff --git a/src/main/java/org/apache/commons/io/output/TaggedWriter.java b/src/main/java/org/apache/commons/io/output/TaggedWriter.java index eb6f79df..828d9ae3 100644 --- a/src/main/java/org/apache/commons/io/output/TaggedWriter.java +++ b/src/main/java/org/apache/commons/io/output/TaggedWriter.java @@ -70,7 +70,7 @@ public class TaggedWriter extends ProxyWriter { private final Serializable tag = UUID.randomUUID(); /** - * Creates a tagging decorator for the given writer. + * Constructs a tagging decorator for the given writer. * * @param proxy writer to be decorated */ diff --git a/src/main/java/org/apache/commons/io/output/TeeWriter.java b/src/main/java/org/apache/commons/io/output/TeeWriter.java index e373bc1d..2db4e6af 100644 --- a/src/main/java/org/apache/commons/io/output/TeeWriter.java +++ b/src/main/java/org/apache/commons/io/output/TeeWriter.java @@ -32,7 +32,7 @@ import java.util.Collection; public class TeeWriter extends ProxyCollectionWriter { /** - * Creates a new filtered collection writer. + * Constructs a new filtered collection writer. * * @param writers Writers to provide the underlying targets. */ @@ -41,7 +41,7 @@ public class TeeWriter extends ProxyCollectionWriter { } /** - * Creates a new filtered collection writer. + * Constructs a new filtered collection writer. * * @param writers Writers to provide the underlying targets. */ diff --git a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java index 9153f0bc..1d8a3a03 100644 --- a/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/ThresholdingOutputStream.java @@ -118,6 +118,7 @@ public class ThresholdingOutputStream extends OutputStream { } catch (final IOException ignored) { // ignore } + // TODO for 4.0: Replace with getOutputStream() getStream().close(); } @@ -129,11 +130,12 @@ public class ThresholdingOutputStream extends OutputStream { @SuppressWarnings("resource") // the underlying stream is managed by a subclass. @Override public void flush() throws IOException { + // TODO for 4.0: Replace with getOutputStream() getStream().flush(); } /** - * Returns the number of bytes that have been written to this output stream. + * Gets the number of bytes that have been written to this output stream. * * @return The number of bytes written. */ @@ -142,19 +144,32 @@ public class ThresholdingOutputStream extends OutputStream { } /** - * Returns the underlying output stream, to which the corresponding {@link OutputStream} methods in this class will + * Gets the underlying output stream, to which the corresponding {@link OutputStream} methods in this class will * ultimately delegate. * * @return The underlying output stream. - * * @throws IOException if an error occurs. + * @deprecated Use {@link #getOutputStream()}. */ + @Deprecated protected OutputStream getStream() throws IOException { + return getOutputStream(); + } + + /** + * Gets the underlying output stream, to which the corresponding {@link OutputStream} methods in this class will + * ultimately delegate. + * + * @return The underlying output stream. + * @throws IOException if an error occurs. + * @since 2.14.0 + */ + protected OutputStream getOutputStream() throws IOException { return outputStreamGetter.apply(this); } /** - * Returns the threshold, in bytes, at which an event will be triggered. + * Gets the threshold, in bytes, at which an event will be triggered. * * @return The threshold point, in bytes. */ @@ -163,7 +178,7 @@ public class ThresholdingOutputStream extends OutputStream { } /** - * Determines whether or not the configured threshold has been exceeded for this output stream. + * Tests whether or not the configured threshold has been exceeded for this output stream. * * @return {@code true} if the threshold has been reached; {@code false} otherwise. */ @@ -212,6 +227,7 @@ public class ThresholdingOutputStream extends OutputStream { @Override public void write(final byte[] b) throws IOException { checkThreshold(b.length); + // TODO for 4.0: Replace with getOutputStream() getStream().write(b); written += b.length; } @@ -229,6 +245,7 @@ public class ThresholdingOutputStream extends OutputStream { @Override public void write(final byte[] b, final int off, final int len) throws IOException { checkThreshold(len); + // TODO for 4.0: Replace with getOutputStream() getStream().write(b, off, len); written += len; } @@ -244,6 +261,7 @@ public class ThresholdingOutputStream extends OutputStream { @Override public void write(final int b) throws IOException { checkThreshold(1); + // TODO for 4.0: Replace with getOutputStream() getStream().write(b); written++; } diff --git a/src/main/java/org/apache/commons/io/output/UncheckedAppendable.java b/src/main/java/org/apache/commons/io/output/UncheckedAppendable.java index 8abda709..e606db4d 100644 --- a/src/main/java/org/apache/commons/io/output/UncheckedAppendable.java +++ b/src/main/java/org/apache/commons/io/output/UncheckedAppendable.java @@ -31,7 +31,7 @@ import java.io.UncheckedIOException; public interface UncheckedAppendable extends Appendable { /** - * Creates a new instance on the given Appendable. + * Constructs a new instance on the given Appendable. * * @param appendable The Appendable to uncheck. * @return a new instance. diff --git a/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java b/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java index c1e9b7ae..91f115db 100644 --- a/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/UncheckedFilterOutputStream.java @@ -91,7 +91,7 @@ public final class UncheckedFilterOutputStream extends FilterOutputStream { } /** - * Creates an output stream filter built on top of the specified underlying output stream. + * Constructs an output stream filter built on top of the specified underlying output stream. * * @param outputStream the underlying output stream, or {@code null} if this instance is to be created without an * underlying stream. diff --git a/src/main/java/org/apache/commons/io/output/UncheckedFilterWriter.java b/src/main/java/org/apache/commons/io/output/UncheckedFilterWriter.java index 14a98226..f152f487 100644 --- a/src/main/java/org/apache/commons/io/output/UncheckedFilterWriter.java +++ b/src/main/java/org/apache/commons/io/output/UncheckedFilterWriter.java @@ -91,7 +91,7 @@ public final class UncheckedFilterWriter extends FilterWriter { } /** - * Creates a new filtered writer. + * Constructs a new filtered writer. * * @param writer a Writer object providing the underlying stream. * @throws NullPointerException if {@code writer} is {@code null}. diff --git a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java index 15f2fb71..232e7186 100644 --- a/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java +++ b/src/main/java/org/apache/commons/io/output/UnsynchronizedByteArrayOutputStream.java @@ -131,7 +131,7 @@ public final class UnsynchronizedByteArrayOutputStream extends AbstractByteArray } /** - * Creates a new byte array output stream. The buffer capacity is initially + * Constructs a new byte array output stream. The buffer capacity is initially * * {@value AbstractByteArrayOutputStream#DEFAULT_SIZE} bytes, though its size increases if necessary. * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. @@ -142,11 +142,11 @@ public final class UnsynchronizedByteArrayOutputStream extends AbstractByteArray } /** - * Creates a new byte array output stream, with a buffer capacity of the specified size, in bytes. + * Constructs a new byte array output stream, with a buffer capacity of the specified size, in bytes. * * @param size the initial size * @throws IllegalArgumentException if size is negative - * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. + * @deprecated Use {@link #builder()}, {@link Builder}, and {@link Builder#get()}. Will be private in 3.0.0. */ @Deprecated public UnsynchronizedByteArrayOutputStream(final int size) { diff --git a/src/site/xdoc/download_io.xml b/src/site/xdoc/download_io.xml index 7432635a..1d7ef8ec 100644 --- a/src/site/xdoc/download_io.xml +++ b/src/site/xdoc/download_io.xml @@ -113,32 +113,32 @@ limitations under the License. </p> </subsection> </section> - <section name="Apache Commons IO 2.13.0 (requires Java 8)"> + <section name="Apache Commons IO 2.14.0 (requires Java 8)"> <subsection name="Binaries"> <table> <tr> - <td><a href="[preferred]/commons/io/binaries/commons-io-2.13.0-bin.tar.gz">commons-io-2.13.0-bin.tar.gz</a></td> - <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.13.0-bin.tar.gz.sha512">sha512</a></td> - <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.13.0-bin.tar.gz.asc">pgp</a></td> + <td><a href="[preferred]/commons/io/binaries/commons-io-2.14.0-bin.tar.gz">commons-io-2.14.0-bin.tar.gz</a></td> + <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.14.0-bin.tar.gz.sha512">sha512</a></td> + <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.14.0-bin.tar.gz.asc">pgp</a></td> </tr> <tr> - <td><a href="[preferred]/commons/io/binaries/commons-io-2.13.0-bin.zip">commons-io-2.13.0-bin.zip</a></td> - <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.13.0-bin.zip.sha512">sha512</a></td> - <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.13.0-bin.zip.asc">pgp</a></td> + <td><a href="[preferred]/commons/io/binaries/commons-io-2.14.0-bin.zip">commons-io-2.14.0-bin.zip</a></td> + <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.14.0-bin.zip.sha512">sha512</a></td> + <td><a href="https://downloads.apache.org/commons/io/binaries/commons-io-2.14.0-bin.zip.asc">pgp</a></td> </tr> </table> </subsection> <subsection name="Source"> <table> <tr> - <td><a href="[preferred]/commons/io/source/commons-io-2.13.0-src.tar.gz">commons-io-2.13.0-src.tar.gz</a></td> - <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.13.0-src.tar.gz.sha512">sha512</a></td> - <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.13.0-src.tar.gz.asc">pgp</a></td> + <td><a href="[preferred]/commons/io/source/commons-io-2.14.0-src.tar.gz">commons-io-2.14.0-src.tar.gz</a></td> + <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.14.0-src.tar.gz.sha512">sha512</a></td> + <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.14.0-src.tar.gz.asc">pgp</a></td> </tr> <tr> - <td><a href="[preferred]/commons/io/source/commons-io-2.13.0-src.zip">commons-io-2.13.0-src.zip</a></td> - <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.13.0-src.zip.sha512">sha512</a></td> - <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.13.0-src.zip.asc">pgp</a></td> + <td><a href="[preferred]/commons/io/source/commons-io-2.14.0-src.zip">commons-io-2.14.0-src.zip</a></td> + <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.14.0-src.zip.sha512">sha512</a></td> + <td><a href="https://downloads.apache.org/commons/io/source/commons-io-2.14.0-src.zip.asc">pgp</a></td> </tr> </table> </subsection> diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index 1d311b0c..1723036e 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -16,247 +16,143 @@ See the License for the specific language governing permissions and limitations under the License. --> <document> - <properties> - <title>Commons IO Overview</title> - <author email="dev@commons.apache.org">Commons Documentation Team</author> - </properties> -<body> -<!-- ================================================== --> -<section name="Apache Commons IO"> -<p> -Apache Commons IO is a library of utilities to assist with developing IO functionality. -</p> -<p> -There are six main areas included: -</p> -<ul> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/package-summary.html">io</a> - - This package defines utility classes for working with streams, readers, writers and files. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/comparator/package-summary.html">comparator</a> - - This package provides various Comparator implementations for Files. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/file/package-summary.html">file</a> - - This package provides extensions in the realm of java.nio.file. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/filefilter/package-summary.html">filefilter</a> - - This package defines an interface (IOFileFilter) that combines both FileFilter and FilenameFilter. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/function/package-summary.html">function</a> - - This package defines IO-only related functional interfaces for lambda expressions and method references. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/input/package-summary.html">input</a> - - This package provides implementations of input classes, such as InputStream and Reader. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/input/buffer/package-summary.html">input.buffer</a> - - This package provides implementations of buffered input classes, such as CircularBufferInputStream and PeekableInputStream. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/monitor/package-summary.html">monitor</a> - - This package provides a component for monitoring file system events (directory and file create, update and delete events). - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/output/package-summary.html">output</a> - - This package provides implementations of output classes, such as OutputStream and Writer. - </li> - <li> - <a - href="apidocs/index.html?org/apache/commons/io/serialization/package-summary.html">serialization</a> - - This package provides a framework for controlling the deserialization of classes. - </li> -</ul> -</section> -<!-- ================================================== --> -<section name="Releases"> - - <subsection name="Commons IO 2.13.0 (requires Java 8)"> - <p> - Commons IO 2.13.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="apidocs/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.12.0 (requires Java 8)"> - <p> - Commons IO 2.12.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.12.0/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.11.0 (requires Java 8)"> - <p> - Commons IO 2.11.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.11.0/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.10.0 (requires Java 8)"> - <p> - Commons IO 2.10.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.10.0/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.9.0 (requires Java 8)"> - <p> - Commons IO 2.9.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.9.0/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.8.0 (requires Java 8)"> - <p> - Commons IO 2.8.0 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.8.0/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.7 (requires Java 8)"> - <p> - Commons IO 2.7 requires a minimum of Java 8 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="changes-report.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.7/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.6 (requires Java 7)"> - <p> - Commons IO 2.6 requires a minimum of Java 7 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="upgradeto2_6.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.6/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.5 (requires Java 6)"> - <p> - Commons IO 2.5 requires a minimum of Java 6 - - <a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> - </p> - <p> - View the - <a href="upgradeto2_5.html">Release Notes</a> - and - <a href="https://javadoc.io/doc/commons-io/commons-io/2.5/index.html">Javadoc API documents</a> - </p> - </subsection> - - <subsection name="Commons IO 2.4 (requires Java 6)"> -<p> - Commons IO 2.4 requires a minimum of JDK 1.6 - -<a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> -</p> -<p> -View the <a href="upgradeto2_4.html">Release Notes</a> and -<a href="https://javadoc.io/doc/commons-io/commons-io/2.4/index.html">Javadoc API documents</a> -</p> -</subsection> - - <subsection name="Commons IO 2.3 (requires Java 6)"> -<p> - Commons IO 2.3 requires a minimum of JDK 1.6 - -<a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> -</p> -<p> -View the <a href="upgradeto2_3.html">Release Notes</a> and -<a href="https://javadoc.io/doc/commons-io/commons-io/2.3/index.html">Javadoc API documents</a> -</p> -</subsection> - -<subsection name="Commons IO 2.2 (requires Java 5)"> -<p> -Commons IO 2.2 requires a minimum of JDK 1.5 - -<a href="https://commons.apache.org/io/download_io.cgi">Download now!</a> -</p> -<p> -View the <a href="upgradeto2_2.html">Release Notes</a> and -<a href="https://javadoc.io/doc/commons-io/commons-io/2.2/index.html">Javadoc API documents</a> -</p> -</subsection> - -<subsection name="Older Releases"> -<p> -For previous releases, see the <a href="https://archive.apache.org/dist/commons/io/">Apache Archive</a> -and <a href="https://javadoc.io/doc/commons-io/commons-io/">Javadoc Archive</a> -</p> -</subsection> - -</section> -<!-- ================================================== --> -<section name="Support"> -<p> -The <a href="mail-lists.html">commons mailing lists</a> act as the main support forum. -The user list is suitable for most library usage queries. -The dev list is intended for the development discussion. -Please remember that the lists are shared between all commons components, -so prefix your email by [io]. -</p> -<p> -Issues may be reported via <a href="issue-tracking.html">ASF JIRA</a>. -Please read the instructions carefully to submit a useful bug report or enhancement request. -</p> -</section> -<!-- ================================================== --> -</body> + <properties> + <title>Commons IO Overview</title> + <author email="dev@commons.apache.org">Commons Documentation Team</author> + </properties> + <body> + <!-- ================================================== --> + <section name="Apache Commons IO"> + <p> + Apache Commons IO is a library of utilities to assist with developing IO functionality. + </p> + <p> + There are six main areas included: + </p> + <ul> + <li> + <a href="apidocs/index.html?org/apache/commons/io/package-summary.html">io</a> + - This package defines utility classes for working with streams, readers, writers and files. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/build/package-summary.html">build</a> + - This package provides classes to implement IO builders. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/charset/package-summary.html">charset</a> + - This package provides classes to work with code from <code>java.nio.charset</code>. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/comparator/package-summary.html">comparator</a> + - This package provides various Comparator implementations for Files and Paths. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/file/package-summary.html">file</a> + - This package provides extensions in the realm of java.nio.file. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/file/attribute/package-summary.html">file.attribute</a> + - This package provides help using <code>java.nio.file.attribute</code> types. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/file/spi/package-summary.html">file SPI</a> + - This package provides extensions in the realm of <code>java.nio.file.spi</code>. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/filefilter/package-summary.html">filefilter</a> + - This package defines an interface (IOFileFilter) that combines both FileFilter and FilenameFilter. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/function/package-summary.html">function</a> + - This package defines IO-only related functional interfaces for lambda expressions and method references. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/input/package-summary.html">input</a> + - This package provides implementations of input classes, such as InputStream and Reader. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/input/buffer/package-summary.html">input.buffer</a> + - This package provides implementations of buffered input classes, such as CircularBufferInputStream and PeekableInputStream. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/monitor/package-summary.html">monitor</a> + - This package provides a component for monitoring file system events (directory and file create, update and delete events). + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/output/package-summary.html">output</a> + - This package provides implementations of output classes, such as OutputStream and Writer. + </li> + <li> + <a href="apidocs/index.html?org/apache/commons/io/serialization/package-summary.html">serialization</a> + - This package provides a framework for controlling the deserialization of classes. + </li> + </ul> + </section> + <!-- ================================================== --> + <section name="Releases"> + + <subsection name="Latest Release (Java 8 and up)"> + <p> + Commons IO 2.13.0 requires a minimum of Java 8 - + <a href="https://commons.apache.org/io/download_io.cgi">Download now</a> + . + </p> + <p> + View the + <a href="changes-report.html">Release Notes</a> + and + <a href="apidocs/index.html">Javadoc API documents</a> + . + </p> + </subsection> + + <subsection name="Previous Releases"> + <p> + See the + <a href="https://archive.apache.org/dist/commons/io/">download archive</a> + and + <a href="https://javadoc.io/doc/commons-io/commons-io/">Javadoc archive</a> + . + </p> + <p> + The Java platform requirements are: + </p> + <ul> + <li>Version 2.14.0 requires Java 8.</li> + <li>Version 2.13.0 requires Java 8.</li> + <li>Version 2.12.0 requires Java 8.</li> + <li>Version 2.11.0 requires Java 8.</li> + <li>Version 2.10.0 requires Java 8.</li> + <li>Version 2.9.0 requires Java 8.</li> + <li>Version 2.8.0 requires Java 8.</li> + <li>Version 2.7 requires Java 8.</li> + <li>Version 2.6 requires Java 7.</li> + <li>Version 2.5 requires Java 6.</li> + <li>Version 2.4 requires Java 6.</li> + <li>Version 2.3 requires Java 6.</li> + <li>Version 2.2 requires Java 5.</li> + </ul> + </subsection> + + </section> + <!-- ================================================== --> + <section name="Support"> + <p> + The + <a href="mail-lists.html">commons mailing lists</a> + act as the main support forum. + The user list is suitable for most library usage queries. + The dev list is intended for the development discussion. + Please remember that the lists are shared between all commons components, + so prefix your email by [io]. + </p> + <p> + Issues may be reported via + <a href="issue-tracking.html">ASF JIRA</a> + . + Please read the instructions carefully to submit a useful bug report or enhancement request. + </p> + </section> + <!-- ================================================== --> + </body> </document> diff --git a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryBaseTest.java b/src/test/java/org/apache/commons/io/AbstractFileUtilsDeleteDirectoryTest.java index 48621add..da77488c 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryBaseTest.java +++ b/src/test/java/org/apache/commons/io/AbstractFileUtilsDeleteDirectoryTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.io.TempDir; /** * Test cases for FileUtils.deleteDirectory() method. */ -public abstract class FileUtilsDeleteDirectoryBaseTest { +public abstract class AbstractFileUtilsDeleteDirectoryTest { @TempDir public File top; diff --git a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java index b90a7ed2..5ac3aa9c 100644 --- a/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java +++ b/src/test/java/org/apache/commons/io/DirectoryWalkerTest.java @@ -47,7 +47,7 @@ public class DirectoryWalkerTest { private final String cancelFileName; private final boolean suppressCancel; - TestCancelWalker(final String cancelFileName,final boolean suppressCancel) { + TestCancelWalker(final String cancelFileName, final boolean suppressCancel) { this.cancelFileName = cancelFileName; this.suppressCancel = suppressCancel; } diff --git a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java index bb47ae23..b5074515 100644 --- a/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java +++ b/src/test/java/org/apache/commons/io/FileCleaningTrackerTest.java @@ -29,6 +29,8 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.lang.ref.ReferenceQueue; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -44,6 +46,7 @@ import org.junit.jupiter.api.Test; public class FileCleaningTrackerTest extends AbstractTempDirTest { private File testFile; + private Path testPath; private FileCleaningTracker theInstance; @@ -63,9 +66,18 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest { } } + private void pauseForDeleteToComplete(Path file) { + int count = 0; + while (Files.exists(file) && count++ < 40) { + TestUtils.sleepQuietly(500L); + file = Paths.get(file.toAbsolutePath().toString()); + } + } + @BeforeEach public void setUp() { testFile = new File(tempDirFile, "file-test.txt"); + testPath = testFile.toPath(); theInstance = newInstance(); } @@ -100,51 +112,59 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest { } @Test - public void testFileCleanerDirectory() throws Exception { - TestUtils.createFile(testFile, 100); + public void testFileCleanerDirectory_ForceStrategy_FileSource() throws Exception { + if (!testFile.getParentFile().exists()) { + throw new IOException("Cannot create file " + testFile + + " as the parent directory does not exist"); + } + try (BufferedOutputStream output = + new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) { + TestUtils.generateTestData(output, 100); + } assertTrue(testFile.exists()); assertTrue(tempDirFile.exists()); Object obj = new Object(); assertEquals(0, theInstance.getTrackCount()); - theInstance.track(tempDirFile, obj); + theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE); assertEquals(1, theInstance.getTrackCount()); obj = null; waitUntilTrackCount(); + pauseForDeleteToComplete(testFile.getParentFile()); assertEquals(0, theInstance.getTrackCount()); - assertTrue(testFile.exists()); // not deleted, as dir not empty - assertTrue(testFile.getParentFile().exists()); // not deleted, as dir not empty + assertFalse(new File(testFile.getPath()).exists(), showFailures()); + assertFalse(testFile.getParentFile().exists(), showFailures()); } @Test - public void testFileCleanerDirectory_ForceStrategy() throws Exception { - if (!testFile.getParentFile().exists()) { - throw new IOException("Cannot create file " + testFile + public void testFileCleanerDirectory_ForceStrategy_PathSource() throws Exception { + if (!Files.exists(testPath.getParent())) { + throw new IOException("Cannot create file " + testPath + " as the parent directory does not exist"); } try (BufferedOutputStream output = - new BufferedOutputStream(Files.newOutputStream(testFile.toPath()))) { + new BufferedOutputStream(Files.newOutputStream(testPath))) { TestUtils.generateTestData(output, 100); } - assertTrue(testFile.exists()); - assertTrue(tempDirFile.exists()); + assertTrue(Files.exists(testPath)); + assertTrue(Files.exists(tempDirPath)); Object obj = new Object(); assertEquals(0, theInstance.getTrackCount()); - theInstance.track(tempDirFile, obj, FileDeleteStrategy.FORCE); + theInstance.track(tempDirPath, obj, FileDeleteStrategy.FORCE); assertEquals(1, theInstance.getTrackCount()); obj = null; waitUntilTrackCount(); - pauseForDeleteToComplete(testFile.getParentFile()); + pauseForDeleteToComplete(testPath.getParent()); assertEquals(0, theInstance.getTrackCount()); - assertFalse(new File(testFile.getPath()).exists(), showFailures()); - assertFalse(testFile.getParentFile().exists(), showFailures()); + assertFalse(Files.exists(testPath), showFailures()); + assertFalse(Files.exists(testPath.getParent()), showFailures()); } @Test @@ -168,6 +188,46 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest { } @Test + public void testFileCleanerDirectoryFileSource() throws Exception { + TestUtils.createFile(testFile, 100); + assertTrue(testFile.exists()); + assertTrue(tempDirFile.exists()); + + Object obj = new Object(); + assertEquals(0, theInstance.getTrackCount()); + theInstance.track(tempDirFile, obj); + assertEquals(1, theInstance.getTrackCount()); + + obj = null; + + waitUntilTrackCount(); + + assertEquals(0, theInstance.getTrackCount()); + assertTrue(testFile.exists()); // not deleted, as dir not empty + assertTrue(testFile.getParentFile().exists()); // not deleted, as dir not empty + } + + @Test + public void testFileCleanerDirectoryPathSource() throws Exception { + TestUtils.createFile(testPath, 100); + assertTrue(Files.exists(testPath)); + assertTrue(Files.exists(tempDirPath)); + + Object obj = new Object(); + assertEquals(0, theInstance.getTrackCount()); + theInstance.track(tempDirPath, obj); + assertEquals(1, theInstance.getTrackCount()); + + obj = null; + + waitUntilTrackCount(); + + assertEquals(0, theInstance.getTrackCount()); + assertTrue(Files.exists(testPath)); // not deleted, as dir not empty + assertTrue(Files.exists(testPath.getParent())); // not deleted, as dir not empty + } + + @Test public void testFileCleanerExitWhenFinished_NoTrackAfter() { assertFalse(theInstance.exitWhenFinished); theInstance.exitWhenFinished(); @@ -187,11 +247,13 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest { final String path = testFile.getPath(); assertFalse(testFile.exists(), "1-testFile exists: " + testFile); - RandomAccessFile r = createRandomAccessFile(); + + // Do NOT used a try-with-resources statement here or the test will fail. + RandomAccessFile raf = createRandomAccessFile(); assertTrue(testFile.exists(), "2-testFile exists"); assertEquals(0, theInstance.getTrackCount(), "3-Track Count"); - theInstance.track(path, r); + theInstance.track(path, raf); assertEquals(1, theInstance.getTrackCount(), "4-Track Count"); assertFalse(theInstance.exitWhenFinished, "5-exitWhenFinished"); assertTrue(theInstance.reaper.isAlive(), "6-reaper.isAlive"); @@ -201,9 +263,9 @@ public class FileCleaningTrackerTest extends AbstractTempDirTest { assertTrue(theInstance.exitWhenFinished, "8-exitWhenFinished"); assertTrue(theInstance.reaper.isAlive(), "9-reaper.isAlive"); - r.close(); + raf.close(); testFile = null; - r = null; + raf = null; waitUntilTrackCount(); pauseForDeleteToComplete(new File(path)); diff --git a/src/test/java/org/apache/commons/io/FileUtilsCleanDirectoryTest.java b/src/test/java/org/apache/commons/io/FileUtilsCleanDirectoryTest.java index 138ebdca..2e28f364 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsCleanDirectoryTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsCleanDirectoryTest.java @@ -17,8 +17,8 @@ package org.apache.commons.io; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.io.File; @@ -123,9 +123,7 @@ public class FileUtilsCleanDirectoryTest extends AbstractTempDirTest { try { // cleanDirectory calls forceDelete - FileUtils.cleanDirectory(tempDirFile); - fail("expected IOException"); - } catch (final IOException e) { + final IOException e = assertThrows(IOException.class, () -> FileUtils.cleanDirectory(tempDirFile)); assertEquals("Unknown I/O error listing contents of directory: " + tempDirFile.getAbsolutePath(), e.getMessage()); } finally { chmod(tempDirFile, 755, false); diff --git a/src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTest.java b/src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTest.java index 8e7194c0..38db7645 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsCleanSymlinksTest.java @@ -192,16 +192,16 @@ public class FileUtilsCleanSymlinksTest { return; } - final File noexistFile = new File(top, "noexist"); + final File nonExistentFile = new File(top, "non-existent"); final File symlinkFile = new File(top, "fakeinner"); final File badSymlinkInPathFile = new File(symlinkFile, "fakeinner"); - final File noexistParentFile = new File("noexist", "file"); + final File nonExistentParentFile = new File("non-existent", "file"); - assertTrue(setupSymlink(noexistFile, symlinkFile)); + assertTrue(setupSymlink(nonExistentFile, symlinkFile)); assertTrue(FileUtils.isSymlink(symlinkFile)); - assertFalse(FileUtils.isSymlink(noexistFile)); - assertFalse(FileUtils.isSymlink(noexistParentFile)); + assertFalse(FileUtils.isSymlink(nonExistentFile)); + assertFalse(FileUtils.isSymlink(nonExistentParentFile)); assertFalse(FileUtils.isSymlink(badSymlinkInPathFile)); } diff --git a/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java b/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java index 9994ef09..ac387856 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsCopyToFileTest.java @@ -60,7 +60,7 @@ public class FileUtilsCopyToFileTest { @BeforeEach public void setUp() throws Exception { testFile = new File(temporaryFolder, "file1-test.txt"); - if(!testFile.getParentFile().exists()) { + if (!testFile.getParentFile().exists()) { throw new IOException("Cannot create file " + testFile + " as the parent directory does not exist"); } diff --git a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryLinuxTest.java b/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryLinuxTest.java index c4e5ccbc..60600ff5 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryLinuxTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryLinuxTest.java @@ -17,8 +17,8 @@ package org.apache.commons.io; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assumptions.assumeTrue; import java.io.File; @@ -35,7 +35,7 @@ import org.junit.jupiter.api.condition.OS; * Tests {@link FileUtils}. */ @DisabledOnOs({OS.WINDOWS, OS.MAC}) -public class FileUtilsDeleteDirectoryLinuxTest extends FileUtilsDeleteDirectoryBaseTest { +public class FileUtilsDeleteDirectoryLinuxTest extends AbstractFileUtilsDeleteDirectoryTest { /** Only runs on Linux. */ private boolean chmod(final File file, final int mode, final boolean recurse) throws InterruptedException { @@ -87,11 +87,8 @@ public class FileUtilsDeleteDirectoryLinuxTest extends FileUtilsDeleteDirectoryB try { // deleteDirectory calls forceDelete - FileUtils.deleteDirectory(nested); - fail("expected IOException"); - } catch (final IOException e) { - final IOExceptionList list = (IOExceptionList) e; - assertTrue(list.getCause(0).getMessage().endsWith("Cannot delete file: " + file.getAbsolutePath())); + final IOExceptionList ioExceptionList = (IOExceptionList) assertThrows(IOException.class, () -> FileUtils.deleteDirectory(nested)); + assertTrue(ioExceptionList.getCause(0).getMessage().endsWith("Cannot delete file: " + file.getAbsolutePath())); } finally { chmod(nested, 755, false); FileUtils.deleteDirectory(nested); @@ -110,9 +107,7 @@ public class FileUtilsDeleteDirectoryLinuxTest extends FileUtilsDeleteDirectoryB try { // cleanDirectory calls forceDelete - FileUtils.deleteDirectory(nested); - fail("expected IOException"); - } catch (final IOException e) { + final IOException e = assertThrows(IOException.class, () -> FileUtils.deleteDirectory(nested)); assertEquals("Unknown I/O error listing contents of directory: " + nested.getAbsolutePath(), e.getMessage()); } finally { chmod(nested, 755, false); diff --git a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryWindowsTest.java b/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryWindowsTest.java index 521ec6e2..5111bf93 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryWindowsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsDeleteDirectoryWindowsTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.condition.OS; * Requires Windows admin karma or you get "You do not have sufficient privilege to perform this operation." */ @EnabledOnOs(OS.WINDOWS) -public class FileUtilsDeleteDirectoryWindowsTest extends FileUtilsDeleteDirectoryBaseTest { +public class FileUtilsDeleteDirectoryWindowsTest extends AbstractFileUtilsDeleteDirectoryTest { @Override protected boolean setupSymlink(final File res, final File link) throws Exception { diff --git a/src/test/java/org/apache/commons/io/FileUtilsTest.java b/src/test/java/org/apache/commons/io/FileUtilsTest.java index 4f2bfebc..4d976c4e 100644 --- a/src/test/java/org/apache/commons/io/FileUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FileUtilsTest.java @@ -2101,7 +2101,7 @@ public class FileUtilsTest extends AbstractTempDirTest { public void testMoveDirectory_Errors() throws Exception { assertThrows(NullPointerException.class, () -> FileUtils.moveDirectory(null, new File("foo"))); assertThrows(NullPointerException.class, () -> FileUtils.moveDirectory(new File("foo"), null)); - assertThrows(FileNotFoundException.class, () -> FileUtils.moveDirectory(new File("nonexistant"), new File("foo"))); + assertThrows(FileNotFoundException.class, () -> FileUtils.moveDirectory(new File("non-existent"), new File("foo"))); final File testFile = new File(tempDirFile, "testMoveDirectoryFile"); if (!testFile.getParentFile().exists()) { @@ -2201,8 +2201,8 @@ public class FileUtilsTest extends AbstractTempDirTest { } assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(testFile1, testFile2, true)); - final File nonexistant = new File(tempDirFile, "testMoveFileNonExistant"); - assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(testFile1, nonexistant, false)); + final File nonExistent = new File(tempDirFile, "testMoveFileNonExistent"); + assertThrows(IOException.class, () -> FileUtils.moveDirectoryToDirectory(testFile1, nonExistent, false)); } @Test @@ -2316,7 +2316,7 @@ public class FileUtilsTest extends AbstractTempDirTest { public void testMoveFile_Errors() throws Exception { assertThrows(NullPointerException.class, () -> FileUtils.moveFile(null, new File("foo"))); assertThrows(NullPointerException.class, () -> FileUtils.moveFile(new File("foo"), null)); - assertThrows(FileNotFoundException.class, () -> FileUtils.moveFile(new File("nonexistant"), new File("foo"))); + assertThrows(FileNotFoundException.class, () -> FileUtils.moveFile(new File("non-existent"), new File("foo"))); assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFile(tempDirFile, new File("foo"))); final File testSourceFile = new File(tempDirFile, "testMoveFileSource"); final File testDestFile = new File(tempDirFile, "testMoveFileSource"); @@ -2384,8 +2384,8 @@ public class FileUtilsTest extends AbstractTempDirTest { } assertThrows(IllegalArgumentException.class, () -> FileUtils.moveFileToDirectory(testFile1, testFile2, true)); - final File nonexistant = new File(tempDirFile, "testMoveFileNonExistant"); - assertThrows(IOException.class, () -> FileUtils.moveFileToDirectory(testFile1, nonexistant, false)); + final File nonExistent = new File(tempDirFile, "testMoveFileNonExistent"); + assertThrows(IOException.class, () -> FileUtils.moveFileToDirectory(testFile1, nonExistent, false)); } @Test @@ -2426,9 +2426,9 @@ public class FileUtilsTest extends AbstractTempDirTest { public void testMoveToDirectory_Errors() throws Exception { assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(null, new File("foo"), true)); assertThrows(NullPointerException.class, () -> FileUtils.moveDirectoryToDirectory(new File("foo"), null, true)); - final File nonexistant = new File(tempDirFile, "nonexistant"); + final File nonExistent = new File(tempDirFile, "non-existent"); final File destDir = new File(tempDirFile, "MoveToDirectoryDestDir"); - assertThrows(IOException.class, () -> FileUtils.moveToDirectory(nonexistant, destDir, true), "Expected IOException when source does not exist"); + assertThrows(IOException.class, () -> FileUtils.moveToDirectory(nonExistent, destDir, true), "Expected IOException when source does not exist"); } @@ -2592,7 +2592,7 @@ public class FileUtilsTest extends AbstractTempDirTest { file.delete(); file.mkdir(); - final File nonEmptyFile = new File(file, "nonEmptyFile" + System.nanoTime()); + final File nonEmptyFile = new File(file, "non-emptyFile" + System.nanoTime()); assertTrue(nonEmptyFile.getParentFile().exists(), () -> "Cannot create file " + nonEmptyFile + " as the parent directory does not exist"); final OutputStream output = new BufferedOutputStream(Files.newOutputStream(nonEmptyFile.toPath())); try { diff --git a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java index 5055eaf4..31b750ef 100644 --- a/src/test/java/org/apache/commons/io/FilenameUtilsTest.java +++ b/src/test/java/org/apache/commons/io/FilenameUtilsTest.java @@ -218,7 +218,7 @@ public class FilenameUtilsTest { @Test public void testGetBaseName() { assertNull(FilenameUtils.getBaseName(null)); - assertEquals("noseperator", FilenameUtils.getBaseName("noseperator.inthispath")); + assertEquals("noseparator", FilenameUtils.getBaseName("noseparator.inthispath")); assertEquals("c", FilenameUtils.getBaseName("a/b/c.txt")); assertEquals("c", FilenameUtils.getBaseName("a/b/c")); assertEquals("", FilenameUtils.getBaseName("a/b/c/")); @@ -249,12 +249,8 @@ public class FilenameUtilsTest { if (FilenameUtils.isSystemWindows()) { // Special case handling for NTFS ADS names - try { - FilenameUtils.getExtension("foo.exe:bar.txt"); - throw new AssertionError("Expected Exception"); - } catch (final IllegalArgumentException e) { - assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage()); - } + final IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> FilenameUtils.getExtension("foo.exe:bar.txt")); + assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage()); } else { // Upwards compatibility: assertEquals("txt", FilenameUtils.getExtension("foo.exe:bar.txt")); @@ -264,7 +260,7 @@ public class FilenameUtilsTest { @Test public void testGetFullPath() { assertNull(FilenameUtils.getFullPath(null)); - assertEquals("", FilenameUtils.getFullPath("noseperator.inthispath")); + assertEquals("", FilenameUtils.getFullPath("noseparator.inthispath")); assertEquals("a/b/", FilenameUtils.getFullPath("a/b/c.txt")); assertEquals("a/b/", FilenameUtils.getFullPath("a/b/c")); assertEquals("a/b/c/", FilenameUtils.getFullPath("a/b/c/")); @@ -306,7 +302,7 @@ public class FilenameUtilsTest { @Test public void testGetFullPathNoEndSeparator() { assertNull(FilenameUtils.getFullPathNoEndSeparator(null)); - assertEquals("", FilenameUtils.getFullPathNoEndSeparator("noseperator.inthispath")); + assertEquals("", FilenameUtils.getFullPathNoEndSeparator("noseparator.inthispath")); assertEquals("a/b", FilenameUtils.getFullPathNoEndSeparator("a/b/c.txt")); assertEquals("a/b", FilenameUtils.getFullPathNoEndSeparator("a/b/c")); assertEquals("a/b/c", FilenameUtils.getFullPathNoEndSeparator("a/b/c/")); @@ -367,7 +363,7 @@ public class FilenameUtilsTest { @Test public void testGetName() { assertNull(FilenameUtils.getName(null)); - assertEquals("noseperator.inthispath", FilenameUtils.getName("noseperator.inthispath")); + assertEquals("noseparator.inthispath", FilenameUtils.getName("noseparator.inthispath")); assertEquals("c.txt", FilenameUtils.getName("a/b/c.txt")); assertEquals("c", FilenameUtils.getName("a/b/c")); assertEquals("", FilenameUtils.getName("a/b/c/")); @@ -377,9 +373,9 @@ public class FilenameUtilsTest { @Test public void testGetPath() { assertNull(FilenameUtils.getPath(null)); - assertEquals("", FilenameUtils.getPath("noseperator.inthispath")); - assertEquals("", FilenameUtils.getPath("/noseperator.inthispath")); - assertEquals("", FilenameUtils.getPath("\\noseperator.inthispath")); + assertEquals("", FilenameUtils.getPath("noseparator.inthispath")); + assertEquals("", FilenameUtils.getPath("/noseparator.inthispath")); + assertEquals("", FilenameUtils.getPath("\\noseparator.inthispath")); assertEquals("a/b/", FilenameUtils.getPath("a/b/c.txt")); assertEquals("a/b/", FilenameUtils.getPath("a/b/c")); assertEquals("a/b/c/", FilenameUtils.getPath("a/b/c/")); @@ -420,9 +416,9 @@ public class FilenameUtilsTest { @Test public void testGetPathNoEndSeparator() { assertNull(FilenameUtils.getPath(null)); - assertEquals("", FilenameUtils.getPath("noseperator.inthispath")); - assertEquals("", FilenameUtils.getPathNoEndSeparator("/noseperator.inthispath")); - assertEquals("", FilenameUtils.getPathNoEndSeparator("\\noseperator.inthispath")); + assertEquals("", FilenameUtils.getPath("noseparator.inthispath")); + assertEquals("", FilenameUtils.getPathNoEndSeparator("/noseparator.inthispath")); + assertEquals("", FilenameUtils.getPathNoEndSeparator("\\noseparator.inthispath")); assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("a/b/c.txt")); assertEquals("a/b", FilenameUtils.getPathNoEndSeparator("a/b/c")); assertEquals("a/b/c", FilenameUtils.getPathNoEndSeparator("a/b/c/")); @@ -585,12 +581,8 @@ public class FilenameUtilsTest { if (FilenameUtils.isSystemWindows()) { // Special case handling for NTFS ADS names - try { - FilenameUtils.indexOfExtension("foo.exe:bar.txt"); - throw new AssertionError("Expected Exception"); - } catch (final IllegalArgumentException e) { - assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage()); - } + final IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> FilenameUtils.indexOfExtension("foo.exe:bar.txt")); + assertEquals("NTFS ADS separator (':') in file name is forbidden.", e.getMessage()); } else { // Upwards compatibility on other systems assertEquals(11, FilenameUtils.indexOfExtension("foo.exe:bar.txt")); @@ -601,7 +593,7 @@ public class FilenameUtilsTest { @Test public void testIndexOfLastSeparator() { assertEquals(-1, FilenameUtils.indexOfLastSeparator(null)); - assertEquals(-1, FilenameUtils.indexOfLastSeparator("noseperator.inthispath")); + assertEquals(-1, FilenameUtils.indexOfLastSeparator("noseparator.inthispath")); assertEquals(3, FilenameUtils.indexOfLastSeparator("a/b/c")); assertEquals(3, FilenameUtils.indexOfLastSeparator("a\\b\\c")); } diff --git a/src/test/java/org/apache/commons/io/IOUtilsCopyTest.java b/src/test/java/org/apache/commons/io/IOUtilsCopyTest.java index 344f34b6..1dbe9c2b 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsCopyTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsCopyTest.java @@ -95,7 +95,7 @@ public class IOUtilsCopyTest { assertEquals(0, in.available(), "Not all bytes were read"); assertEquals(inData.length, baout.size(), "Sizes differ"); assertArrayEquals(inData, baout.toByteArray(), "Content differs"); - assertEquals(inData.length,count); + assertEquals(inData.length, count); } /** @@ -161,7 +161,7 @@ public class IOUtilsCopyTest { assertEquals(0, in.available(), "Not all bytes were read"); assertEquals(inData.length, baout.size(), "Sizes differ"); assertArrayEquals(inData, baout.toByteArray(), "Content differs"); - assertEquals(inData.length,count); + assertEquals(inData.length, count); } @SuppressWarnings({ "resource", "deprecation" }) // 'in' is deliberately not closed diff --git a/src/test/java/org/apache/commons/io/IOUtilsMultithreadedSkipTest.java b/src/test/java/org/apache/commons/io/IOUtilsMultithreadedSkipTest.java new file mode 100644 index 00000000..9db0d67b --- /dev/null +++ b/src/test/java/org/apache/commons/io/IOUtilsMultithreadedSkipTest.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Random; +import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.function.Supplier; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * See Jira ticket IO-802. + */ +public class IOUtilsMultithreadedSkipTest { + + private static final String FIXTURE = "TIKA-4065.bin"; + long seed = 1; + private final ThreadLocal<byte[]> threadLocal = ThreadLocal.withInitial(() -> new byte[4096]); + + private int[] generateExpected(final InputStream is, final int[] skips) throws IOException { + final int[] testBytes = new int[skips.length]; + for (int i = 0; i < skips.length; i++) { + try { + IOUtils.skipFully(is, skips[i]); + testBytes[i] = is.read(); + } catch (final EOFException e) { + testBytes[i] = -1; + } + } + return testBytes; + } + + private int[] generateSkips(final byte[] bytes, final int numSkips, final Random random) { + final int[] skips = new int[numSkips]; + for (int i = 0; i < skips.length; i++) { + skips[i] = random.nextInt(bytes.length / numSkips) + bytes.length / 10; + } + return skips; + } + + private InputStream inflate(final byte[] deflated) throws IOException { + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(new InflaterInputStream(new ByteArrayInputStream(deflated), new Inflater(true)), bos); + return new ByteArrayInputStream(bos.toByteArray()); + } + + @BeforeEach + public void setUp() { + // Not the best random we can use but good enough here. + seed = new Random().nextLong(); + } + + private void testSkipFullyOnInflaterInputStream(final Supplier<byte[]> baSupplier) throws Exception { + final long thisSeed = seed; + // thisSeed = -727624427837034313l; + final Random random = new Random(thisSeed); + final byte[] bytes; + try (final InputStream inputStream = getClass().getResourceAsStream(FIXTURE)) { + bytes = IOUtils.toByteArray(inputStream); + } + final int numSkips = (random.nextInt(bytes.length) / 100) + 1; + + final int[] skips = generateSkips(bytes, numSkips, random); + final int[] expected; + try (final InputStream inflate = inflate(bytes)) { + expected = generateExpected(inflate, skips); + } + + final int numThreads = 2; + final int iterations = 100; + final ExecutorService executorService = Executors.newFixedThreadPool(numThreads); + final ExecutorCompletionService<Integer> executorCompletionService = new ExecutorCompletionService<>(executorService); + + for (int i = 0; i < numThreads; i++) { + executorCompletionService.submit(() -> { + for (int iteration = 0; iteration < iterations; iteration++) { + try (InputStream is = new InflaterInputStream(new ByteArrayInputStream(bytes), new Inflater(true))) { + for (int skipIndex = 0; skipIndex < skips.length; skipIndex++) { + try { + IOUtils.skipFully(is, skips[skipIndex], baSupplier); + final int c = is.read(); + assertEquals(expected[skipIndex], c, "failed on seed=" + seed + " iteration=" + iteration); + } catch (final EOFException e) { + assertEquals(expected[skipIndex], is.read(), "failed on " + "seed=" + seed + " iteration=" + iteration); + } + } + } + } + return 1; + }); + } + + int finished = 0; + while (finished < numThreads) { + // blocking + final Future<Integer> future = executorCompletionService.take(); + try { + future.get(); + } catch (final Exception e) { + // printStackTrace() for simpler debugging + e.printStackTrace(); + fail("failed on seed=" + seed); + } + finished++; + } + } + + @Test + public void testSkipFullyOnInflaterInputStream_New_bytes() throws Exception { + testSkipFullyOnInflaterInputStream(() -> new byte[4096]); + } + + @Test + public void testSkipFullyOnInflaterInputStream_ThreadLocal() throws Exception { + testSkipFullyOnInflaterInputStream(threadLocal::get); + } + +} diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java index 909893df..e361e885 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java @@ -60,6 +60,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.List; +import java.util.function.Supplier; import java.util.stream.Stream; import org.apache.commons.io.function.IOConsumer; @@ -1310,13 +1311,53 @@ public class IOUtilsTest { public void testSkipFully_InputStream() throws Exception { final int size = 1027; - final InputStream input = new ByteArrayInputStream(new byte[size]); - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); + try (final InputStream input = new ByteArrayInputStream(new byte[size])) { + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); - IOUtils.skipFully(input, 0); - IOUtils.skipFully(input, size - 1); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2), "Should have failed with IOException"); - IOUtils.closeQuietly(input); + IOUtils.skipFully(input, 0); + IOUtils.skipFully(input, size - 1); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2), "Should have failed with IOException"); + } + } + + @Test + public void testSkipFully_InputStream_Buffer_New_bytes() throws Exception { + final int size = 1027; + final Supplier<byte[]> bas = () -> new byte[size]; + try (final InputStream input = new ByteArrayInputStream(new byte[size])) { + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException"); + + IOUtils.skipFully(input, 0, bas); + IOUtils.skipFully(input, size - 1, bas); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException"); + } + } + + @Test + public void testSkipFully_InputStream_Buffer_Reuse_bytes() throws Exception { + final int size = 1027; + final byte[] ba = new byte[size]; + final Supplier<byte[]> bas = () -> ba; + try (final InputStream input = new ByteArrayInputStream(new byte[size])) { + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, bas), "Should have failed with IllegalArgumentException"); + + IOUtils.skipFully(input, 0, bas); + IOUtils.skipFully(input, size - 1, bas); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, bas), "Should have failed with IOException"); + } + } + + @Test + public void testSkipFully_InputStream_Buffer_Reuse_ThreadLocal() throws Exception { + final int size = 1027; + final ThreadLocal<byte[]> tl = ThreadLocal.withInitial(() -> new byte[size]); + try (final InputStream input = new ByteArrayInputStream(new byte[size])) { + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1, tl::get), "Should have failed with IllegalArgumentException"); + + IOUtils.skipFully(input, 0, tl::get); + IOUtils.skipFully(input, size - 1, tl::get); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 2, tl::get), "Should have failed with IOException"); + } } @Test @@ -1336,13 +1377,12 @@ public class IOUtilsTest { @Test public void testSkipFully_Reader() throws Exception { final int size = 1027; - final Reader input = new CharArrayReader(new char[size]); - - IOUtils.skipFully(input, 0); - IOUtils.skipFully(input, size - 3); - assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); - assertThrows(IOException.class, () -> IOUtils.skipFully(input, 5), "Should have failed with IOException"); - IOUtils.closeQuietly(input); + try (final Reader input = new CharArrayReader(new char[size])) { + IOUtils.skipFully(input, 0); + IOUtils.skipFully(input, size - 3); + assertThrows(IllegalArgumentException.class, () -> IOUtils.skipFully(input, -1), "Should have failed with IllegalArgumentException"); + assertThrows(IOException.class, () -> IOUtils.skipFully(input, 5), "Should have failed with IOException"); + } } @Test @@ -1472,11 +1512,11 @@ public class IOUtilsTest { @Test public void testToByteArray_Reader() throws IOException { final String charsetName = UTF_8; - final byte[] expecteds = charsetName.getBytes(charsetName); - byte[] actuals = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expecteds))); - assertArrayEquals(expecteds, actuals); - actuals = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expecteds)), charsetName); - assertArrayEquals(expecteds, actuals); + final byte[] expected = charsetName.getBytes(charsetName); + byte[] actual = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expected))); + assertArrayEquals(expected, actual); + actual = IOUtils.toByteArray(new InputStreamReader(new ByteArrayInputStream(expected)), charsetName); + assertArrayEquals(expected, actual); } @Test diff --git a/src/test/java/org/apache/commons/io/UncheckedIOTest.java b/src/test/java/org/apache/commons/io/UncheckedIOTest.java deleted file mode 100644 index 38aae531..00000000 --- a/src/test/java/org/apache/commons/io/UncheckedIOTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.io; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.io.ByteArrayInputStream; - -import org.apache.commons.io.function.IOBiFunction; -import org.apache.commons.io.function.IOConsumer; -import org.apache.commons.io.function.IOFunction; -import org.apache.commons.io.function.IORunnable; -import org.apache.commons.io.function.IOSupplier; -import org.apache.commons.io.function.IOTriFunction; -import org.apache.commons.io.function.Uncheck; -import org.junit.jupiter.api.Test; - -/** - * Tests {@link Uncheck}. - */ -public class UncheckedIOTest { - - private static final byte[] BYTES = {'a', 'b'}; - - private ByteArrayInputStream newInputStream() { - return new ByteArrayInputStream(BYTES); - } - - /** - * Tests {@link Uncheck#accept(IOConsumer, Object)}. - */ - @Test - public void testAccept() { - final ByteArrayInputStream stream = newInputStream(); - Uncheck.accept(n -> stream.skip(n), 1); - assertEquals('b', Uncheck.get(stream::read).intValue()); - } - - /** - * Tests {@link Uncheck#apply(IOFunction, Object)}. - */ - @Test - public void testApply1() { - final ByteArrayInputStream stream = newInputStream(); - assertEquals(1, Uncheck.apply(n -> stream.skip(n), 1).intValue()); - assertEquals('b', Uncheck.get(stream::read).intValue()); - } - - /** - * Tests {@link Uncheck#apply(IOBiFunction, Object, Object)}. - */ - @Test - public void testApply2() { - final ByteArrayInputStream stream = newInputStream(); - final byte[] buf = new byte[BYTES.length]; - assertEquals(1, Uncheck.apply((o, l) -> stream.read(buf, o, l), 0, 1).intValue()); - assertEquals('a', buf[0]); - } - - /** - * Tests {@link Uncheck#apply(IOTriFunction, Object, Object, Object)}. - */ - @Test - public void testApply3() { - final ByteArrayInputStream stream = newInputStream(); - final byte[] buf = new byte[BYTES.length]; - assertEquals(1, Uncheck.apply((b, o, l) -> stream.read(b, o, l), buf, 0, 1).intValue()); - assertEquals('a', buf[0]); - } - - /** - * Tests {@link Uncheck#get(IOSupplier)}. - */ - @Test - public void testGet() { - assertEquals('a', Uncheck.get(() -> newInputStream().read()).intValue()); - } - - /** - * Tests {@link Uncheck#run(IORunnable)}. - */ - @Test - public void testRun() { - final ByteArrayInputStream stream = newInputStream(); - Uncheck.run(() -> stream.skip(1)); - assertEquals('b', Uncheck.get(stream::read).intValue()); - } -} diff --git a/src/test/java/org/apache/commons/io/build/AbstractStreamBuilderTest.java b/src/test/java/org/apache/commons/io/build/AbstractStreamBuilderTest.java new file mode 100644 index 00000000..425ba4a5 --- /dev/null +++ b/src/test/java/org/apache/commons/io/build/AbstractStreamBuilderTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.build; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +/** + * Tests {@link AbstractStreamBuilder}. + */ +public class AbstractStreamBuilderTest { + + public static class Builder extends AbstractStreamBuilder<char[], Builder> { + + @Override + public char[] get() { + final char[] arr = new char[getBufferSize()]; + Arrays.fill(arr, 'a'); + return arr; + } + + } + + private void assertResult(final char[] arr, final int size) { + assertNotNull(arr); + assertEquals(size, arr.length); + for (final char c : arr) { + assertEquals('a', c); + } + } + + protected Builder builder() { + return new Builder(); + } + + @Test + public void testBufferSizeChecker() { + // sanity + final Builder builder = builder(); + assertResult(builder.get(), builder.getBufferSize()); + // basic failure + assertThrows(IllegalArgumentException.class, () -> builder().setBufferSizeMax(2).setBufferSize(3)); + // reset + assertResult(builder.setBufferSizeMax(2).setBufferSizeMax(0).setBufferSize(3).get(), 3); + // resize + assertResult(builder().setBufferSizeMax(2).setBufferSizeChecker(i -> 100).setBufferSize(3).get(), 100); + } +} diff --git a/src/test/java/org/apache/commons/io/comparator/SizeFileComparatorTest.java b/src/test/java/org/apache/commons/io/comparator/SizeFileComparatorTest.java index 50f34c59..34e2236a 100644 --- a/src/test/java/org/apache/commons/io/comparator/SizeFileComparatorTest.java +++ b/src/test/java/org/apache/commons/io/comparator/SizeFileComparatorTest.java @@ -95,9 +95,9 @@ public class SizeFileComparatorTest extends ComparatorAbstractTest { * Test a file which doesn't exist. */ @Test - public void testNonexistantFile() { - final File nonexistantFile = new File(FileUtils.current(), "nonexistant.txt"); - assertFalse(nonexistantFile.exists()); - assertTrue(comparator.compare(nonexistantFile, moreFile) < 0, "less"); + public void testNonExistentFile() { + final File nonExistentFile = new File(FileUtils.current(), "non-existent.txt"); + assertFalse(nonExistentFile.exists()); + assertTrue(comparator.compare(nonExistentFile, moreFile) < 0, "less"); } } diff --git a/src/test/java/org/apache/commons/io/file/PathWrapper.java b/src/test/java/org/apache/commons/io/file/AbstractPathWrapper.java index 2bf1daac..674ee3de 100644 --- a/src/test/java/org/apache/commons/io/file/PathWrapper.java +++ b/src/test/java/org/apache/commons/io/file/AbstractPathWrapper.java @@ -37,7 +37,7 @@ import java.util.function.Consumer; * * @since 2.12.0 */ -public abstract class PathWrapper implements Path { +public abstract class AbstractPathWrapper implements Path { /** * The path delegate. @@ -49,7 +49,7 @@ public abstract class PathWrapper implements Path { * * @param path The path to wrap. */ - protected PathWrapper(final Path path) { + protected AbstractPathWrapper(final Path path) { this.path = Objects.requireNonNull(path, "path"); } @@ -73,10 +73,10 @@ public abstract class PathWrapper implements Path { if (this == obj) { return true; } - if (!(obj instanceof PathWrapper)) { + if (!(obj instanceof AbstractPathWrapper)) { return false; } - final PathWrapper other = (PathWrapper) obj; + final AbstractPathWrapper other = (AbstractPathWrapper) obj; return Objects.equals(path, other.path); } diff --git a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java index fb0fe15e..e61c5cfe 100644 --- a/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java +++ b/src/test/java/org/apache/commons/io/file/CopyDirectoryVisitorTest.java @@ -56,7 +56,7 @@ public class CopyDirectoryVisitorTest extends TestArguments { final CopyDirectoryVisitor visitFileTree = PathUtils.visitFileTree(supplier.get(), sourceDir.get()); assertCounts(1, 0, 0, visitFileTree); assertArrayEquals(EXPECTED_COPY_OPTIONS, visitFileTree.getCopyOptions()); - assertEquals(sourceDir.get(), ((PathWrapper) visitFileTree.getSourceDirectory()).get()); + assertEquals(sourceDir.get(), ((AbstractPathWrapper) visitFileTree.getSourceDirectory()).get()); assertEquals(sourceDir, visitFileTree.getSourceDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); assertEquals(targetDir, visitFileTree.getTargetDirectory()); diff --git a/src/test/java/org/apache/commons/io/file/DeletablePath.java b/src/test/java/org/apache/commons/io/file/DeletablePath.java index 28aa20b9..9f9fbf07 100644 --- a/src/test/java/org/apache/commons/io/file/DeletablePath.java +++ b/src/test/java/org/apache/commons/io/file/DeletablePath.java @@ -28,7 +28,7 @@ import org.apache.commons.io.file.Counters.PathCounters; * * @since 2.12.0 */ -public class DeletablePath extends PathWrapper implements Closeable { +public class DeletablePath extends AbstractPathWrapper implements Closeable { /** * Constructs a new instance wrapping the given delegate. diff --git a/src/test/java/org/apache/commons/io/file/FilesUncheckTest.java b/src/test/java/org/apache/commons/io/file/FilesUncheckTest.java index 18823532..4fa73681 100644 --- a/src/test/java/org/apache/commons/io/file/FilesUncheckTest.java +++ b/src/test/java/org/apache/commons/io/file/FilesUncheckTest.java @@ -165,6 +165,11 @@ public class FilesUncheckTest { } @Test + public void testFind() { + assertNotNull(FilesUncheck.find(FILE_PATH_EMPTY, 0, (t, u) -> false)); + } + + @Test public void testGetAttribute() { assertEquals(0L, FilesUncheck.getAttribute(FILE_PATH_EMPTY, "basic:size", LinkOption.NOFOLLOW_LINKS)); } diff --git a/src/test/java/org/apache/commons/io/file/PathUtilsDeleteDirectoryTest.java b/src/test/java/org/apache/commons/io/file/PathUtilsDeleteDirectoryTest.java index 121b2dc0..a22630d4 100644 --- a/src/test/java/org/apache/commons/io/file/PathUtilsDeleteDirectoryTest.java +++ b/src/test/java/org/apache/commons/io/file/PathUtilsDeleteDirectoryTest.java @@ -18,9 +18,13 @@ package org.apache.commons.io.file; import static org.apache.commons.io.file.CounterAssertions.assertCounts; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; import java.nio.file.Paths; import org.junit.jupiter.api.Test; @@ -30,6 +34,18 @@ import org.junit.jupiter.api.Test; */ public class PathUtilsDeleteDirectoryTest extends AbstractTempDirTest { + @Test + public void testDeleteAbsentDirectory() throws IOException { + final Path absent = tempDirPath.resolve("ThisDirectoryDoesNotExist"); + assertFalse(Files.exists(absent)); + final Class<NoSuchFileException> expectedType = NoSuchFileException.class; + assertThrows(expectedType, () -> PathUtils.deleteDirectory(absent)); + assertThrows(expectedType, () -> PathUtils.deleteDirectory(absent, StandardDeleteOption.OVERRIDE_READ_ONLY)); + assertThrows(expectedType, () -> PathUtils.deleteDirectory(absent, PathUtils.EMPTY_DELETE_OPTION_ARRAY)); + // This will throw if not empty. + Files.deleteIfExists(tempDirPath); + } + /** * Tests a directory with one file of size 0. */ diff --git a/src/test/java/org/apache/commons/io/file/PathUtilsTest.java b/src/test/java/org/apache/commons/io/file/PathUtilsTest.java index 860ae36c..622937e4 100644 --- a/src/test/java/org/apache/commons/io/file/PathUtilsTest.java +++ b/src/test/java/org/apache/commons/io/file/PathUtilsTest.java @@ -99,7 +99,7 @@ public class PathUtilsTest extends AbstractTempDirTest { return Files.getLastModifiedTime(file).toMillis(); } - private Path getNonExistantPath() { + private Path getNonExistentPath() { return Paths.get("/does not exist/for/certain"); } @@ -252,13 +252,13 @@ public class PathUtilsTest extends AbstractTempDirTest { @Test public void testGetLastModifiedFileTime_Path_Absent() throws IOException { - assertNull(PathUtils.getLastModifiedFileTime(getNonExistantPath())); + assertNull(PathUtils.getLastModifiedFileTime(getNonExistentPath())); } @Test public void testGetLastModifiedFileTime_Path_FileTime_Absent() throws IOException { final FileTime fromMillis = FileTime.fromMillis(0); - assertEquals(fromMillis, PathUtils.getLastModifiedFileTime(getNonExistantPath(), fromMillis)); + assertEquals(fromMillis, PathUtils.getLastModifiedFileTime(getNonExistentPath(), fromMillis)); } @Test diff --git a/src/test/java/org/apache/commons/io/filefilter/ConditionalFileFilterAbstractTest.java b/src/test/java/org/apache/commons/io/filefilter/AbstractConditionalFileFilterTest.java index daffdb40..5a99d620 100644 --- a/src/test/java/org/apache/commons/io/filefilter/ConditionalFileFilterAbstractTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/AbstractConditionalFileFilterTest.java @@ -27,7 +27,7 @@ import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public abstract class ConditionalFileFilterAbstractTest extends IOFileFilterAbstractTest { +public abstract class AbstractConditionalFileFilterTest extends AbstractIOFileFilterTest { private static final String TEST_FILE_NAME_PREFIX = "TestFile"; private static final String TEST_FILE_TYPE = ".tst"; diff --git a/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java index 4ed27be3..ca6f8874 100644 --- a/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/AbstractFilterTest.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; import org.apache.commons.io.IOCase; import org.junit.jupiter.api.io.TempDir; @@ -43,16 +44,24 @@ public class AbstractFilterTest { @TempDir public File temporaryFolder; - void assertFiltering(final IOFileFilter filter, final File file, final boolean expected) { + void assertFiltering(final IOFileFilter filter, final File file, final boolean expected) throws IOException { // Note. This only tests the (File, String) version if the parent of // the File passed in is not null assertEquals(expected, filter.accept(file), "Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); if (file != null && file.getParentFile() != null) { assertEquals(expected, filter.accept(file.getParentFile(), file.getName()), - "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file); + "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file); + final Path path = file.toPath(); + assertEquals(expected, filter.accept(path, null) != FileVisitResult.TERMINATE, filter::toString); + if (Files.isRegularFile(path)) { + assertEquals(expected, filter.accept(path, Files.readAttributes(path, BasicFileAttributes.class)) != FileVisitResult.TERMINATE, + filter::toString); + } + assertEquals(expected, filter.matches(path), filter::toString); } else if (file == null) { - assertEquals(expected, filter.accept(file), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); + assertEquals(expected, filter.accept(null), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); + assertEquals(expected, filter.matches(null), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); } assertNotNull(filter.toString()); } @@ -62,19 +71,23 @@ public class AbstractFilterTest { // the File passed in is not null final FileVisitResult expectedFileVisitResult = AbstractFileFilter.toDefaultFileVisitResult(expected); assertEquals(expectedFileVisitResult, filter.accept(path, null), - "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); + "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); if (path != null && path.getParent() != null) { assertEquals(expectedFileVisitResult, filter.accept(path, null), - "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); + "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); + assertEquals(expectedFileVisitResult != FileVisitResult.TERMINATE, filter.matches(path), + "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); } else if (path == null) { assertEquals(expectedFileVisitResult, filter.accept(path, null), - "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for null"); + "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for null"); + assertEquals(expectedFileVisitResult != FileVisitResult.TERMINATE, filter.matches(path), + "Filter(Path, Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for null"); } assertNotNull(filter.toString()); } - void assertFooBarFileFiltering(IOFileFilter filter) { + void assertFooBarFileFiltering(IOFileFilter filter) throws IOException { assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("bar"), true); @@ -84,7 +97,7 @@ public class AbstractFilterTest { assertFiltering(filter, new File("bar").toPath(), true); assertFiltering(filter, new File("fred").toPath(), false); - filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.SENSITIVE); + filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.SENSITIVE); assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("bar"), true); assertFiltering(filter, new File("FOO"), false); @@ -94,7 +107,7 @@ public class AbstractFilterTest { assertFiltering(filter, new File("FOO").toPath(), false); assertFiltering(filter, new File("BAR").toPath(), false); - filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.INSENSITIVE); + filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.INSENSITIVE); assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("bar"), true); assertFiltering(filter, new File("FOO"), true); @@ -104,7 +117,7 @@ public class AbstractFilterTest { assertFiltering(filter, new File("FOO").toPath(), true); assertFiltering(filter, new File("BAR").toPath(), true); - filter = new NameFileFilter(new String[] {"foo", "bar"}, IOCase.SYSTEM); + filter = new NameFileFilter(new String[] { "foo", "bar" }, IOCase.SYSTEM); assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("bar"), true); assertFiltering(filter, new File("FOO"), WINDOWS); @@ -114,7 +127,7 @@ public class AbstractFilterTest { assertFiltering(filter, new File("FOO").toPath(), WINDOWS); assertFiltering(filter, new File("BAR").toPath(), WINDOWS); - filter = new NameFileFilter(new String[] {"foo", "bar"}, null); + filter = new NameFileFilter(new String[] { "foo", "bar" }, null); assertFiltering(filter, new File("foo"), true); assertFiltering(filter, new File("bar"), true); assertFiltering(filter, new File("FOO"), false); diff --git a/src/test/java/org/apache/commons/io/filefilter/IOFileFilterAbstractTest.java b/src/test/java/org/apache/commons/io/filefilter/AbstractIOFileFilterTest.java index 5009ec5d..f5ba2791 100644 --- a/src/test/java/org/apache/commons/io/filefilter/IOFileFilterAbstractTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/AbstractIOFileFilterTest.java @@ -22,7 +22,7 @@ import java.io.File; import java.util.Objects; import java.util.stream.Stream; -public abstract class IOFileFilterAbstractTest { +public abstract class AbstractIOFileFilterTest { class TesterFalseFileFilter extends FalseFileFilter { @@ -93,6 +93,8 @@ public abstract class IOFileFilterAbstractTest { public static void assertFileFiltering(final int testNumber, final IOFileFilter filter, final File file, final boolean expected) { assertEquals(expected, filter.accept(file), "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); + assertEquals(expected, filter.matches(file.toPath()), + "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); } public static void assertFilenameFiltering(final int testNumber, final IOFileFilter filter, final File file, final boolean expected) { @@ -107,14 +109,18 @@ public abstract class IOFileFilterAbstractTest { assertEquals(expected, filter.accept(file), "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); assertEquals(expected, filter.accept(file.toPath(), null), - "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); + "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); if (file != null && file.getParentFile() != null) { assertEquals(expected, filter.accept(file.getParentFile(), file.getName()), "test " + testNumber + " Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file); + assertEquals(expected, filter.matches(file.toPath()), + "test " + testNumber + " Filter(File) " + filter.getClass().getName() + " not " + expected + " for " + file); } else if (file == null) { assertEquals(expected, filter.accept(file), "test " + testNumber + " Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); + assertEquals(expected, filter.matches(null), + "test " + testNumber + " Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); } } diff --git a/src/test/java/org/apache/commons/io/filefilter/AndFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/AndFileFilterTest.java index 28886bdf..3dffd9a2 100644 --- a/src/test/java/org/apache/commons/io/filefilter/AndFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/AndFileFilterTest.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test; /** * Tests {@link AndFileFilter}. */ -public class AndFileFilterTest extends ConditionalFileFilterAbstractTest { +public class AndFileFilterTest extends AbstractConditionalFileFilterTest { private static final String DEFAULT_WORKING_PATH = "./AndFileFilterTestCase/"; private static final String WORKING_PATH_NAME_PROPERTY_KEY = AndFileFilterTest.class.getName() + ".workingDirectory"; diff --git a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java index 3b8f4bcd..858c4a19 100644 --- a/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/FileFilterTest.java @@ -29,6 +29,7 @@ import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; import java.io.FilenameFilter; +import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.FileVisitResult; @@ -153,7 +154,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testAnd() { + public void testAnd() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; assertFiltering(trueFilter.and(trueFilter), new File("foo.test"), true); @@ -163,7 +164,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testAnd2() { + public void testAnd2() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; assertFiltering(new AndFileFilter(trueFilter, trueFilter), new File("foo.test"), true); @@ -181,7 +182,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testAndArray() { + public void testAndArray() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; assertFiltering(new AndFileFilter(trueFilter, trueFilter, trueFilter), new File("foo.test"), true); @@ -252,7 +253,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testDelegateFileFilter() { + public void testDelegateFileFilter() throws IOException { final OrFileFilter orFilter = new OrFileFilter(); final File testFile = new File("test.txt"); @@ -276,7 +277,7 @@ public class FileFilterTest extends AbstractFilterTest { @SuppressWarnings("deprecation") @Test - public void testDeprecatedWildcard() { + public void testDeprecatedWildcard() throws IOException { IOFileFilter filter = new WildcardFilter("*.txt"); final List<String> patternList = Arrays.asList("*.txt", "*.xml", "*.gif"); final IOFileFilter listFilter = new WildcardFilter(patternList); @@ -328,9 +329,14 @@ public class FileFilterTest extends AbstractFilterTest { assertFiltering(listFilter, new File("Test.gif").toPath(), true); assertFiltering(listFilter, new File("Test.bmp").toPath(), false); + // File assertTrue(listFilter.accept(txtFile)); assertFalse(listFilter.accept(bmpFile)); assertFalse(listFilter.accept(dirFile)); + // Path + assertTrue(listFilter.matches(txtPath)); + assertFalse(listFilter.matches(bmpPath)); + assertFalse(listFilter.matches(dirPath)); // assertEquals(FileVisitResult.CONTINUE, listFilter.accept(txtPath, null)); assertEquals(FileVisitResult.TERMINATE, listFilter.accept(bmpPath, null)); @@ -350,7 +356,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testDirectory() { + public void testDirectory() throws IOException { // XXX: This test presumes the current working dir is the base dir of the source checkout. final IOFileFilter filter = new DirectoryFileFilter(); @@ -427,7 +433,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testFalse() { + public void testFalse() throws IOException { final IOFileFilter filter = FileFilterUtils.falseFileFilter(); assertFiltering(filter, new File("foo.test"), false); assertFiltering(filter, new File("foo.test").toPath(), false); @@ -442,13 +448,13 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testFileEqualsFilter() { + public void testFileEqualsFilter() throws IOException { assertFooBarFileFiltering( new FileEqualsFileFilter(new File("foo")).or(new FileEqualsFileFilter(new File("bar")))); } @Test - public void testFileFilterUtils_and() { + public void testFileFilterUtils_and() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; assertFiltering(FileFilterUtils.and(trueFilter, trueFilter, trueFilter), new File("foo.test"), true); @@ -458,7 +464,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testFileFilterUtils_or() { + public void testFileFilterUtils_or() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; final File testFile = new File("foo.test"); @@ -469,7 +475,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testFiles() { + public void testFiles() throws IOException { // XXX: This test presumes the current working dir is the base dir of the source checkout. final IOFileFilter filter = FileFileFilter.INSTANCE; @@ -695,7 +701,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testHidden() { + public void testHidden() throws IOException { final File hiddenDirFile = new File(SVN_DIR_NAME); final Path hiddenDirPath = hiddenDirFile.toPath(); if (hiddenDirFile.exists()) { @@ -792,8 +798,6 @@ public class FileFilterTest extends AbstractFilterTest { assertFiltering(filter, dir, false); } - // ----------------------------------------------------------------------- - @Test public void testMagicNumberFileFilterString() throws Exception { final byte[] classFileMagicNumber = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; @@ -1032,7 +1036,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testNameFilter() { + public void testNameFilter() throws IOException { assertFooBarFileFiltering(new NameFileFilter("foo", "bar")); } @@ -1056,7 +1060,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testNegate() { + public void testNegate() throws IOException { final IOFileFilter filter = FileFilterUtils.notFileFilter(FileFilterUtils.trueFileFilter()); assertFiltering(filter, new File("foo.test"), false); assertFiltering(filter, new File("foo"), false); @@ -1072,7 +1076,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testOr() { + public void testOr() throws IOException { final IOFileFilter trueFilter = TrueFileFilter.INSTANCE; final IOFileFilter falseFilter = FalseFileFilter.INSTANCE; final File testFile = new File("foo.test"); @@ -1109,21 +1113,23 @@ public class FileFilterTest extends AbstractFilterTest { assertTrue(orFilter.accept(testFile.getParentFile(), testFile.getName())); assertEquals(FileVisitResult.CONTINUE, orFilter.accept(testPath, null)); + assertTrue(orFilter.matches(testPath)); orFilter.removeFileFilter(trueFilter); assertFalse(orFilter.accept(testFile.getParentFile(), testFile.getName())); assertEquals(FileVisitResult.TERMINATE, orFilter.accept(testPath, null)); + assertFalse(orFilter.matches(testPath)); assertThrows(NullPointerException.class, () -> new OrFileFilter(falseFilter, null)); } @Test - public void testPathEqualsFilter() { + public void testPathEqualsFilter() throws IOException { assertFooBarFileFiltering( new PathEqualsFileFilter(Paths.get("foo")).or(new PathEqualsFileFilter(Paths.get("bar")))); } @Test - public void testPrefix() { + public void testPrefix() throws IOException { IOFileFilter filter = new PrefixFileFilter("foo", "bar"); final File testFile = new File("test"); final Path testPath = testFile.toPath(); @@ -1165,6 +1171,9 @@ public class FileFilterTest extends AbstractFilterTest { // assertEquals(FileVisitResult.CONTINUE, filter.accept(testPath, null)); assertEquals(FileVisitResult.TERMINATE, filter.accept(fredPath, null)); + // + assertTrue(filter.matches(testPath)); + assertFalse(filter.matches(fredPath)); final List<String> prefixes = Arrays.asList("foo", "fre"); final IOFileFilter listFilter = new PrefixFileFilter(prefixes); @@ -1174,6 +1183,9 @@ public class FileFilterTest extends AbstractFilterTest { // assertEquals(FileVisitResult.TERMINATE, listFilter.accept(testPath, null)); assertEquals(FileVisitResult.CONTINUE, listFilter.accept(fredPath, null)); + // + assertFalse(listFilter.matches(testPath)); + assertTrue(listFilter.matches(fredPath)); assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String) null)); assertThrows(NullPointerException.class, () -> new PrefixFileFilter((String[]) null)); @@ -1181,7 +1193,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testPrefixCaseInsensitive() { + public void testPrefixCaseInsensitive() throws IOException { IOFileFilter filter = new PrefixFileFilter(new String[] {"foo", "bar"}, IOCase.INSENSITIVE); assertFiltering(filter, new File("foo.test1"), true); @@ -1310,7 +1322,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testSuffix() { + public void testSuffix() throws IOException { IOFileFilter filter = new SuffixFileFilter("tes", "est"); final File testFile = new File("test"); final Path testPath = testFile.toPath(); @@ -1348,6 +1360,9 @@ public class FileFilterTest extends AbstractFilterTest { // assertEquals(FileVisitResult.CONTINUE, filter.accept(testPath, null)); assertEquals(FileVisitResult.TERMINATE, filter.accept(fredPath, null)); + // + assertTrue(filter.matches(testPath)); + assertFalse(filter.matches(fredPath)); final List<String> prefixes = Arrays.asList("ood", "red"); final IOFileFilter listFilter = new SuffixFileFilter(prefixes); @@ -1364,7 +1379,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testSuffixCaseInsensitive() { + public void testSuffixCaseInsensitive() throws IOException { IOFileFilter filter = new SuffixFileFilter(new String[] {"tes", "est"}, IOCase.INSENSITIVE); assertFiltering(filter, new File("foo.tes"), true); @@ -1398,7 +1413,7 @@ public class FileFilterTest extends AbstractFilterTest { } @Test - public void testTrue() { + public void testTrue() throws IOException { final IOFileFilter filter = FileFilterUtils.trueFileFilter(); assertFiltering(filter, new File("foo.test"), true); assertFiltering(filter, new File("foo"), true); diff --git a/src/test/java/org/apache/commons/io/filefilter/OrFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/OrFileFilterTest.java index 932bca08..76df6f43 100644 --- a/src/test/java/org/apache/commons/io/filefilter/OrFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/OrFileFilterTest.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.BeforeEach; /** * Tests {@link IOFileFilter}. */ -public class OrFileFilterTest extends ConditionalFileFilterAbstractTest { +public class OrFileFilterTest extends AbstractConditionalFileFilterTest { private static final String DEFAULT_WORKING_PATH = "./OrFileFilterTestCase/"; private static final String WORKING_PATH_NAME_PROPERTY_KEY = OrFileFilterTest.class.getName() + ".workingDirectory"; diff --git a/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java new file mode 100644 index 00000000..b2ab9821 --- /dev/null +++ b/src/test/java/org/apache/commons/io/filefilter/PathMatcherFileFilterTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.filefilter; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; + +import org.apache.commons.io.FileSystem; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link PathMatcherFileFilter}. + */ +public class PathMatcherFileFilterTest extends AbstractFilterTest { + + @Test + public void testGlob() throws IOException { + @SuppressWarnings("resource") + final IOFileFilter filter = new PathMatcherFileFilter(FileSystems.getDefault().getPathMatcher("glob:*.txt")); + final File file1 = new File("log.txt"); + final File file2 = new File("log.TXT"); + // + assertTrue(filter.accept(file1)); + assertEquals(!FileSystem.getCurrent().isCaseSensitive(), filter.accept(file2)); + assertTrue(filter.accept(file1.getParentFile(), file1.getName())); + assertEquals(!FileSystem.getCurrent().isCaseSensitive(), filter.accept(file2.getParentFile(), file2.getName())); + assertFiltering(filter, file1, true); + assertFiltering(filter, file1.toPath(), true); + } + +} diff --git a/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java index e80ec10d..c0571299 100644 --- a/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/RegexFileFilterTest.java @@ -49,9 +49,13 @@ public class RegexFileFilterTest { if (file != null && file.getParentFile() != null) { assertEquals(expected, filter.accept(file.getParentFile(), file.getName()), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file); + assertEquals(expected, filter.matches(file.toPath()), + "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for " + file); } else if (file == null) { assertEquals(expected, filter.accept(file), "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); + assertEquals(expected, filter.matches(null), + "Filter(File, String) " + filter.getClass().getName() + " not " + expected + " for null"); } // Just don't blow up assertNotNull(filter.toString()); @@ -62,7 +66,9 @@ public class RegexFileFilterTest { // the Path passed in is not null final FileVisitResult expectedFileVisitResult = AbstractFileFilter.toDefaultFileVisitResult(expected); assertEquals(expectedFileVisitResult, filter.accept(path, null), - "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); + "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); + assertEquals(expectedFileVisitResult != FileVisitResult.TERMINATE, filter.matches(path), + "Filter(Path) " + filter.getClass().getName() + " not " + expectedFileVisitResult + " for " + path); if (path != null && path.getParent() != null) { assertEquals(expectedFileVisitResult, filter.accept(path, null), diff --git a/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java index 380ad0cb..49478a8b 100644 --- a/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/SymbolicLinkFileFilterTest.java @@ -56,7 +56,8 @@ public class SymbolicLinkFileFilterTest { private static Path targetDirPath; // hard directory Path private static Path testLinkDirPath; // symbolic link to hardDirectory private static File testLinkDirFile; - private static File missingFile; // non-existent file + private static File missingFileFile; // non-existent file + private static Path missingFilePath; // non-existent file private static SymbolicLinkFileFilter filter; // Mock filter for testing on Windows. @@ -127,7 +128,8 @@ public class SymbolicLinkFileFilterTest { targetDirFile = targetDirPath.toFile(); testLinkDirPath = symbolicLinkCreator.apply(parentDirectoryPath.resolve(DIRECTORY_LINK_NAME), targetDirPath); testLinkDirFile = testLinkDirPath.toFile(); - missingFile = new File(parentDirectoryPath.toFile(), MISSING); + missingFileFile = new File(parentDirectoryPath.toFile(), MISSING); + missingFilePath = missingFileFile.toPath(); } @Test @@ -147,7 +149,7 @@ public class SymbolicLinkFileFilterTest { @Test public void testFileFilter_missingFile() { - assertFalse(filter.accept(missingFile)); + assertFalse(filter.accept(missingFileFile)); } @Test @@ -183,30 +185,37 @@ public class SymbolicLinkFileFilterTest { @Test public void testPathFilter_HardDirectory() { assertEquals(FileVisitResult.TERMINATE, filter.accept(targetDirPath, null)); + assertFalse(filter.matches(targetDirPath)); } @Test public void testPathFilter_HardFile() { assertEquals(FileVisitResult.TERMINATE, filter.accept(testTargetPath, null)); + assertFalse(filter.matches(testTargetPath)); } @Test public void testPathFilter_Link() { assertEquals(FileVisitResult.CONTINUE, filter.accept(testLinkPath, null)); + assertTrue(filter.matches(testLinkPath)); + } @Test public void testPathFilter_missingFile() { - assertEquals(FileVisitResult.TERMINATE, filter.accept(missingFile.toPath(), null)); + assertEquals(FileVisitResult.TERMINATE, filter.accept(missingFilePath, null)); + assertFalse(filter.matches(missingFilePath)); } @Test public void testPathFilter_PathLink() { assertEquals(FileVisitResult.CONTINUE, filter.accept(testLinkDirPath, null)); + assertTrue(filter.matches(testLinkDirPath)); } @Test public void testSymbolicLinkFileFilter() { assertEquals(FileVisitResult.TERMINATE, SymbolicLinkFileFilter.INSTANCE.accept(PathUtils.current(), null)); + assertFalse(filter.matches(PathUtils.current())); } } diff --git a/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java b/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java index b9ab69ce..44ee1fa9 100644 --- a/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java +++ b/src/test/java/org/apache/commons/io/filefilter/WildcardFileFilterTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; +import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Path; import java.util.Arrays; @@ -34,7 +35,7 @@ import org.junit.jupiter.api.Test; public class WildcardFileFilterTest extends AbstractFilterTest { @Test - public void testWildcard() { + public void testWildcard() throws IOException { IOFileFilter filter = new WildcardFileFilter("*.txt"); assertFiltering(filter, new File("log.txt"), true); assertFiltering(filter, new File("log.TXT"), false); @@ -138,13 +139,18 @@ public class WildcardFileFilterTest extends AbstractFilterTest { final Path bmpPath = bmpFile.toPath(); final File dirFile = new File("src/java"); final Path dirPath = dirFile.toPath(); + // File assertTrue(listFilter.accept(txtFile)); assertFalse(listFilter.accept(bmpFile)); assertFalse(listFilter.accept(dirFile)); + // Path + assertTrue(listFilter.matches(txtPath)); + assertFalse(listFilter.matches(bmpPath)); + assertFalse(listFilter.matches(dirPath)); // - assertEquals(FileVisitResult.CONTINUE, listFilter.accept(txtFile.toPath(), null)); - assertEquals(FileVisitResult.TERMINATE, listFilter.accept(bmpFile.toPath(), null)); - assertEquals(FileVisitResult.TERMINATE, listFilter.accept(dirFile.toPath(), null)); + assertEquals(FileVisitResult.CONTINUE, listFilter.accept(txtPath, null)); + assertEquals(FileVisitResult.TERMINATE, listFilter.accept(bmpPath, null)); + assertEquals(FileVisitResult.TERMINATE, listFilter.accept(dirPath, null)); assertTrue(listFilter.accept(txtFile.getParentFile(), txtFile.getName())); assertFalse(listFilter.accept(bmpFile.getParentFile(), bmpFile.getName())); diff --git a/src/test/java/org/apache/commons/io/function/IOBaseStreamTest.java b/src/test/java/org/apache/commons/io/function/IOBaseStreamTest.java index 45f68c95..1c05418c 100644 --- a/src/test/java/org/apache/commons/io/function/IOBaseStreamTest.java +++ b/src/test/java/org/apache/commons/io/function/IOBaseStreamTest.java @@ -107,14 +107,14 @@ public class IOBaseStreamTest { baseStream = createStreamOfPaths(); ioBaseStream = createIOBaseStream(); ioBaseStreamPath = createIOBaseStreamPath(); - ioBaseStreamAdapter = createIOBaseStreamApapter(); + ioBaseStreamAdapter = createIOBaseStreamAdapter(); } private IOBaseStreamFixture<Path, ?, Stream<Path>> createIOBaseStream() { return new IOBaseStreamFixture<>(createStreamOfPaths()); } - private IOStream<Path> createIOBaseStreamApapter() { + private IOStream<Path> createIOBaseStreamAdapter() { return IOStreamAdapter.adapt(createStreamOfPaths()); } diff --git a/src/test/java/org/apache/commons/io/function/IOIntSupplierTest.java b/src/test/java/org/apache/commons/io/function/IOIntSupplierTest.java new file mode 100644 index 00000000..b23f8f67 --- /dev/null +++ b/src/test/java/org/apache/commons/io/function/IOIntSupplierTest.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link IOIntSupplier}. + */ +public class IOIntSupplierTest { + + private AtomicInteger atomicInt; + + private int getThrowsIO(final IOIntSupplier supplier) throws IOException { + return supplier.getAsInt(); + } + + private int getThrowsNone(final IOIntSupplier supplier) { + return supplier.asIntSupplier().getAsInt(); + } + + @BeforeEach + public void initEach() { + atomicInt = new AtomicInteger(); + } + + @Test + public void testAsSupplier() { + assertThrows(UncheckedIOException.class, () -> TestConstants.THROWING_IO_INT_SUPPLIER.asIntSupplier().getAsInt()); + assertEquals(1, getThrowsNone(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1))); + assertEquals(1, atomicInt.get()); + assertNotEquals(TestConstants.THROWING_IO_INT_SUPPLIER.asIntSupplier(), TestConstants.THROWING_IO_INT_SUPPLIER.asIntSupplier()); + } + + @Test + public void testGet() throws IOException { + assertThrows(IOException.class, () -> TestConstants.THROWING_IO_INT_SUPPLIER.getAsInt()); + assertThrows(IOException.class, () -> { + throw new IOException(); + }); + assertEquals(1, getThrowsIO(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1))); + assertEquals(1, atomicInt.get()); + } + +}
\ No newline at end of file diff --git a/src/test/java/org/apache/commons/io/function/IOLongSupplierTest.java b/src/test/java/org/apache/commons/io/function/IOLongSupplierTest.java new file mode 100644 index 00000000..07748ded --- /dev/null +++ b/src/test/java/org/apache/commons/io/function/IOLongSupplierTest.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.io.function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.util.concurrent.atomic.AtomicLong; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link IOLongSupplier}. + */ +public class IOLongSupplierTest { + + private AtomicLong atomicLong; + + private long getThrowsIO(final IOLongSupplier supplier) throws IOException { + return supplier.getAsLong(); + } + + private long getThrowsNone(final IOLongSupplier supplier) { + return supplier.asSupplier().getAsLong(); + } + + @BeforeEach + public void initEach() { + atomicLong = new AtomicLong(); + } + + @Test + public void testAsSupplier() throws IOException { + assertThrows(UncheckedIOException.class, () -> TestConstants.THROWING_IO_LONG_SUPPLIER.asSupplier().getAsLong()); + assertEquals(1L, getThrowsNone(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L))); + assertEquals(1L, atomicLong.get()); + assertNotEquals(TestConstants.THROWING_IO_LONG_SUPPLIER.asSupplier(), TestConstants.THROWING_IO_LONG_SUPPLIER.asSupplier()); + } + + @Test + public void testGet() throws IOException { + assertThrows(IOException.class, () -> TestConstants.THROWING_IO_LONG_SUPPLIER.getAsLong()); + assertThrows(IOException.class, () -> { + throw new IOException(); + }); + assertEquals(1L, getThrowsIO(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L))); + assertEquals(1L, atomicLong.get()); + } + +}
\ No newline at end of file diff --git a/src/test/java/org/apache/commons/io/function/IOStreamTest.java b/src/test/java/org/apache/commons/io/function/IOStreamTest.java index 4fb8abe3..198a361c 100644 --- a/src/test/java/org/apache/commons/io/function/IOStreamTest.java +++ b/src/test/java/org/apache/commons/io/function/IOStreamTest.java @@ -214,7 +214,7 @@ public class IOStreamTest { public void testForaAllIOConsumer() throws IOException { // compile vs type assertThrows(IOException.class, () -> IOStream.of("A").forAll(TestUtils.throwingIOConsumer())); - // compile vs inlnine + // compile vs inline assertThrows(IOException.class, () -> IOStream.of("A").forAll(e -> { throw new IOException("Failure"); })); @@ -229,7 +229,7 @@ public class IOStreamTest { public void testForaAllIOConsumerBiFunction() throws IOException { // compile vs type assertThrows(IOException.class, () -> IOStream.of("A").forAll(TestUtils.throwingIOConsumer(), (i, e) -> e)); - // compile vs inlnine + // compile vs inline assertThrows(IOException.class, () -> IOStream.of("A").forAll(e -> { throw new IOException("Failure"); }, (i, e) -> e)); @@ -244,7 +244,7 @@ public class IOStreamTest { public void testForaAllIOConsumerBiFunctionNull() throws IOException { // compile vs type assertDoesNotThrow(() -> IOStream.of("A").forAll(TestUtils.throwingIOConsumer(), null)); - // compile vs inlnine + // compile vs inline assertDoesNotThrow(() -> IOStream.of("A").forAll(e -> { throw new IOException("Failure"); }, null)); @@ -259,7 +259,7 @@ public class IOStreamTest { public void testForEachIOConsumerOfQsuperT() throws IOException { // compile vs type assertThrows(IOException.class, () -> IOStream.of("A").forEach(TestUtils.throwingIOConsumer())); - // compile vs inlnine + // compile vs inline assertThrows(IOException.class, () -> IOStream.of("A").forEach(e -> { throw new IOException("Failure"); })); @@ -274,7 +274,7 @@ public class IOStreamTest { public void testForEachOrdered() throws IOException { // compile vs type assertThrows(IOException.class, () -> IOStream.of("A").forEach(TestUtils.throwingIOConsumer())); - // compile vs inlnine + // compile vs inline assertThrows(IOException.class, () -> IOStream.of("A").forEach(e -> { throw new IOException("Failure"); })); diff --git a/src/test/java/org/apache/commons/io/function/IOSupplierTest.java b/src/test/java/org/apache/commons/io/function/IOSupplierTest.java index 4b18f48f..7a8e94f5 100644 --- a/src/test/java/org/apache/commons/io/function/IOSupplierTest.java +++ b/src/test/java/org/apache/commons/io/function/IOSupplierTest.java @@ -35,7 +35,7 @@ public class IOSupplierTest { private AtomicReference<String> ref1; - private String getThrows(final IOSupplier<String> supplier) throws IOException { + private String getThrowsIO(final IOSupplier<String> supplier) throws IOException { return supplier.get(); } @@ -62,7 +62,7 @@ public class IOSupplierTest { assertThrows(IOException.class, () -> { throw new IOException(); }); - assertEquals("new1", getThrows(() -> TestUtils.compareAndSetThrowsIO(ref1, "new1"))); + assertEquals("new1", getThrowsIO(() -> TestUtils.compareAndSetThrowsIO(ref1, "new1"))); assertEquals("new1", ref1.get()); } diff --git a/src/test/java/org/apache/commons/io/function/TestConstants.java b/src/test/java/org/apache/commons/io/function/TestConstants.java index 5f0581c7..bafe7ef0 100644 --- a/src/test/java/org/apache/commons/io/function/TestConstants.java +++ b/src/test/java/org/apache/commons/io/function/TestConstants.java @@ -44,6 +44,10 @@ class TestConstants { static IOFunction<Object, Object> THROWING_IO_FUNCTION = t -> throwIOException(); + static IOIntSupplier THROWING_IO_INT_SUPPLIER = () -> throwIOException(); + + static IOLongSupplier THROWING_IO_LONG_SUPPLIER = () -> throwIOException(); + static IOPredicate<Object> THROWING_IO_PREDICATE = t -> throwIOException(); static IOQuadFunction<Object, Object, Object, Object, Object> THROWING_IO_QUAD_FUNCTION = (t, u, v, w) -> throwIOException(); diff --git a/src/test/java/org/apache/commons/io/function/TestUtils.java b/src/test/java/org/apache/commons/io/function/TestUtils.java index 9b6f3aa7..9d05f026 100644 --- a/src/test/java/org/apache/commons/io/function/TestUtils.java +++ b/src/test/java/org/apache/commons/io/function/TestUtils.java @@ -18,10 +18,34 @@ package org.apache.commons.io.function; import java.io.IOException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; class TestUtils { + static int compareAndSetThrowsIO(final AtomicInteger ref, final int update) throws IOException { + return compareAndSetThrowsIO(ref, 0, update); + } + + static int compareAndSetThrowsIO(final AtomicInteger ref, final int expected, final int update) throws IOException { + if (!ref.compareAndSet(expected, update)) { + throw new IOException("Unexpected"); + } + return ref.get(); // same as update + } + + static long compareAndSetThrowsIO(final AtomicLong ref, final long update) throws IOException { + return compareAndSetThrowsIO(ref, 0, update); + } + + static long compareAndSetThrowsIO(final AtomicLong ref, final long expected, final long update) throws IOException { + if (!ref.compareAndSet(expected, update)) { + throw new IOException("Unexpected"); + } + return ref.get(); // same as update + } + static <T> T compareAndSetThrowsIO(final AtomicReference<T> ref, final T update) throws IOException { return compareAndSetThrowsIO(ref, null, update); } diff --git a/src/test/java/org/apache/commons/io/function/UncheckTest.java b/src/test/java/org/apache/commons/io/function/UncheckTest.java index ee73abc6..3eff77e8 100644 --- a/src/test/java/org/apache/commons/io/function/UncheckTest.java +++ b/src/test/java/org/apache/commons/io/function/UncheckTest.java @@ -20,11 +20,17 @@ package org.apache.commons.io.function; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UncheckedIOException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; +import org.apache.commons.io.input.BrokenInputStream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -33,18 +39,46 @@ import org.junit.jupiter.api.Test; */ public class UncheckTest { + private static final byte[] BYTES = { 'a', 'b' }; + private static final String CAUSE_MESSAGE = "CauseMessage"; + private static final String CUSTOM_MESSAGE = "Custom message"; + + private AtomicInteger atomicInt; + private AtomicLong atomicLong; private AtomicReference<String> ref1; private AtomicReference<String> ref2; private AtomicReference<String> ref3; - private AtomicReference<String> ref4; + private void assertUncheckedIOException(final IOException expected, final UncheckedIOException e) { + assertEquals(CUSTOM_MESSAGE, e.getMessage()); + final IOException cause = e.getCause(); + assertEquals(expected.getClass(), cause.getClass()); + assertEquals(CAUSE_MESSAGE, cause.getMessage()); + } + @BeforeEach public void initEach() { ref1 = new AtomicReference<>(); ref2 = new AtomicReference<>(); ref3 = new AtomicReference<>(); ref4 = new AtomicReference<>(); + atomicInt = new AtomicInteger(); + atomicLong = new AtomicLong(); + } + + private ByteArrayInputStream newInputStream() { + return new ByteArrayInputStream(BYTES); + } + + /** + * Tests {@link Uncheck#accept(IOConsumer, Object)}. + */ + @Test + public void testAccept() { + final ByteArrayInputStream stream = newInputStream(); + Uncheck.accept(n -> stream.skip(n), 1); + assertEquals('b', Uncheck.get(stream::read).intValue()); } @Test @@ -87,6 +121,38 @@ public class UncheckTest { assertEquals("new3", ref3.get()); } + /** + * Tests {@link Uncheck#apply(IOFunction, Object)}. + */ + @Test + public void testApply1() { + final ByteArrayInputStream stream = newInputStream(); + assertEquals(1, Uncheck.apply(n -> stream.skip(n), 1).intValue()); + assertEquals('b', Uncheck.get(stream::read).intValue()); + } + + /** + * Tests {@link Uncheck#apply(IOBiFunction, Object, Object)}. + */ + @Test + public void testApply2() { + final ByteArrayInputStream stream = newInputStream(); + final byte[] buf = new byte[BYTES.length]; + assertEquals(1, Uncheck.apply((o, l) -> stream.read(buf, o, l), 0, 1).intValue()); + assertEquals('a', buf[0]); + } + + /** + * Tests {@link Uncheck#apply(IOTriFunction, Object, Object, Object)}. + */ + @Test + public void testApply3() { + final ByteArrayInputStream stream = newInputStream(); + final byte[] buf = new byte[BYTES.length]; + assertEquals(1, Uncheck.apply((b, o, l) -> stream.read(b, o, l), buf, 0, 1).intValue()); + assertEquals('a', buf[0]); + } + @Test public void testApplyIOBiFunctionOfTURTU() { assertThrows(UncheckedIOException.class, () -> Uncheck.apply((t, u) -> { @@ -148,8 +214,12 @@ public class UncheckTest { assertEquals("new3", ref3.get()); } + /** + * Tests {@link Uncheck#get(IOSupplier)}. + */ @Test public void testGet() { + assertEquals('a', Uncheck.get(() -> newInputStream().read()).intValue()); assertThrows(UncheckedIOException.class, () -> Uncheck.get(() -> { throw new IOException(); })); @@ -159,7 +229,89 @@ public class UncheckTest { } @Test + public void testGetAsInt() { + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(() -> { + throw new IOException(); + })); + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(TestConstants.THROWING_IO_INT_SUPPLIER)); + assertEquals(1, Uncheck.getAsInt(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1))); + assertEquals(1, atomicInt.get()); + } + + @Test + public void testGetAsIntMessage() { + // No exception + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(() -> { + throw new IOException(); + }, () -> CUSTOM_MESSAGE)); + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsInt(TestConstants.THROWING_IO_INT_SUPPLIER, () -> CUSTOM_MESSAGE)); + assertEquals(1, Uncheck.getAsInt(() -> TestUtils.compareAndSetThrowsIO(atomicInt, 1), () -> CUSTOM_MESSAGE)); + assertEquals(1, atomicInt.get()); + // exception + final IOException expected = new IOException(CAUSE_MESSAGE); + try { + Uncheck.getAsInt(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE); + fail(); + } catch (final UncheckedIOException e) { + assertUncheckedIOException(expected, e); + } + } + + @Test + public void testGetAsLong() { + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(() -> { + throw new IOException(); + })); + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(TestConstants.THROWING_IO_LONG_SUPPLIER)); + assertEquals(1L, Uncheck.getAsLong(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L))); + assertEquals(1L, atomicLong.get()); + } + + @Test + public void testGetAsLongMessage() { + // No exception + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(() -> { + throw new IOException(); + }, () -> CUSTOM_MESSAGE)); + assertThrows(UncheckedIOException.class, () -> Uncheck.getAsLong(TestConstants.THROWING_IO_LONG_SUPPLIER, () -> CUSTOM_MESSAGE)); + assertEquals(1L, Uncheck.getAsLong(() -> TestUtils.compareAndSetThrowsIO(atomicLong, 1L), () -> CUSTOM_MESSAGE)); + assertEquals(1L, atomicLong.get()); + // exception + final IOException expected = new IOException(CAUSE_MESSAGE); + try { + Uncheck.getAsLong(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE); + fail(); + } catch (final UncheckedIOException e) { + assertUncheckedIOException(expected, e); + } + } + + /** + * Tests {@link Uncheck#get(IOSupplier, Supplier)}. + */ + @Test + public void testGetMessage() { + // No exception + assertEquals('a', Uncheck.get(() -> newInputStream().read()).intValue(), () -> CUSTOM_MESSAGE); + // Exception + final IOException expected = new IOException(CAUSE_MESSAGE); + try { + Uncheck.get(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE); + fail(); + } catch (final UncheckedIOException e) { + assertUncheckedIOException(expected, e); + } + } + + /** + * Tests {@link Uncheck#run(IORunnable)}. + */ + @Test public void testRun() { + final ByteArrayInputStream stream = newInputStream(); + Uncheck.run(() -> stream.skip(1)); + assertEquals('b', Uncheck.get(stream::read).intValue()); + // assertThrows(UncheckedIOException.class, () -> Uncheck.run(() -> { throw new IOException(); })); @@ -168,6 +320,27 @@ public class UncheckTest { assertEquals("new1", ref1.get()); } + /** + * Tests {@link Uncheck#run(IORunnable, Supplier))}. + * + * @throws IOException + */ + @Test + public void testRunMessage() throws IOException { + // No exception + final ByteArrayInputStream stream = newInputStream(); + Uncheck.run(() -> stream.skip(1), () -> CUSTOM_MESSAGE); + assertEquals('b', Uncheck.get(stream::read).intValue()); + final IOException expected = new IOException(CAUSE_MESSAGE); + // Exception + try { + Uncheck.run(() -> new BrokenInputStream(expected).read(), () -> CUSTOM_MESSAGE); + fail(); + } catch (final UncheckedIOException e) { + assertUncheckedIOException(expected, e); + } + } + @Test public void testTest() { assertThrows(UncheckedIOException.class, () -> Uncheck.test(t -> { diff --git a/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java b/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java index 97c3f1d3..7bc997e0 100644 --- a/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/CharSequenceInputStreamTest.java @@ -425,19 +425,6 @@ public class CharSequenceInputStreamTest { } } - private void testSingleByteRead(final String testString, final String charsetName) throws IOException { - final byte[] bytes = testString.getBytes(charsetName); - try (InputStream in = new CharSequenceInputStream(testString, charsetName, 512)) { - for (final byte b : bytes) { - final int read = in.read(); - assertTrue(read >= 0, "read " + read + " >=0 "); - assertTrue(read <= 255, "read " + read + " <= 255"); - assertEquals(b, (byte) read, "Should agree with input"); - } - assertEquals(-1, in.read()); - } - } - @Test public void testResetCharset() { assertNotNull(CharSequenceInputStream.builder().setReader(new StringReader("\uD800")).setCharset((Charset) null).getCharset()); @@ -453,6 +440,19 @@ public class CharSequenceInputStreamTest { assertNotNull(CharSequenceInputStream.builder().setReader(new StringReader("\uD800")).setCharset((String) null).getCharset()); } + private void testSingleByteRead(final String testString, final String charsetName) throws IOException { + final byte[] bytes = testString.getBytes(charsetName); + try (InputStream in = new CharSequenceInputStream(testString, charsetName, 512)) { + for (final byte b : bytes) { + final int read = in.read(); + assertTrue(read >= 0, "read " + read + " >=0 "); + assertTrue(read <= 255, "read " + read + " <= 255"); + assertEquals(b, (byte) read, "Should agree with input"); + } + assertEquals(-1, in.read()); + } + } + @Test public void testSingleByteRead_RequiredCharsets() throws IOException { for (final String csName : getRequiredCharsetNames()) { diff --git a/src/test/java/org/apache/commons/io/input/NullInputStreamTest.java b/src/test/java/org/apache/commons/io/input/NullInputStreamTest.java index 77f3c074..219c5308 100644 --- a/src/test/java/org/apache/commons/io/input/NullInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/NullInputStreamTest.java @@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import java.io.EOFException; import java.io.IOException; @@ -75,12 +74,8 @@ public class NullInputStreamTest { assertTrue(input.markSupported(), "Mark Should be Supported"); // No Mark - try { - input.reset(); - fail("Read limit exceeded, expected IOException "); - } catch (final IOException e) { - assertEquals("No position has been marked", e.getMessage(), "No Mark IOException message"); - } + final IOException noMarkException = assertThrows(IOException.class, input::reset); + assertEquals("No position has been marked", noMarkException.getMessage(), "No Mark IOException message"); for (; position < 3; position++) { assertEquals(position, input.read(), "Read Before Mark [" + position + "]"); @@ -103,13 +98,9 @@ public class NullInputStreamTest { } // Reset after read limit passed - try { - input.reset(); - fail("Read limit exceeded, expected IOException "); - } catch (final IOException e) { - assertEquals("Marked position [" + position + "] is no longer valid - passed the read limit [" + readlimit + "]", e.getMessage(), + final IOException resetException = assertThrows(IOException.class, input::reset, "Read limit exceeded, expected IOException"); + assertEquals("Marked position [" + position + "] is no longer valid - passed the read limit [" + readlimit + "]", resetException.getMessage(), "Read limit IOException message"); - } } } @@ -118,19 +109,11 @@ public class NullInputStreamTest { final InputStream input = new TestNullInputStream(100, false, true); assertFalse(input.markSupported(), "Mark Should NOT be Supported"); - try { - input.mark(5); - fail("mark() should throw UnsupportedOperationException"); - } catch (final UnsupportedOperationException e) { - assertEquals(MARK_RESET_NOT_SUPPORTED, e.getMessage(), "mark() error message"); - } + final UnsupportedOperationException markException = assertThrows(UnsupportedOperationException.class, () -> input.mark(5)); + assertEquals(MARK_RESET_NOT_SUPPORTED, markException.getMessage(), "mark() error message"); - try { - input.reset(); - fail("reset() should throw UnsupportedOperationException"); - } catch (final UnsupportedOperationException e) { - assertEquals(MARK_RESET_NOT_SUPPORTED, e.getMessage(), "reset() error message"); - } + final UnsupportedOperationException resetException = assertThrows(UnsupportedOperationException.class, input::reset); + assertEquals(MARK_RESET_NOT_SUPPORTED, resetException.getMessage(), "reset() error message"); input.close(); } @@ -149,12 +132,8 @@ public class NullInputStreamTest { assertEquals(0, input.available(), "Available after End of File"); // Test reading after the end of file - try { - final int result = input.read(); - fail("Should have thrown an IOException, byte=[" + result + "]"); - } catch (final IOException e) { - assertEquals("Read after end of file", e.getMessage()); - } + final IOException e = assertThrows(IOException.class, input::read); + assertEquals("Read after end of file", e.getMessage()); // Close - should reset input.close(); @@ -185,12 +164,8 @@ public class NullInputStreamTest { assertEquals(-1, count3, "Read 3 (EOF)"); // Test reading after the end of file - try { - final int count4 = input.read(bytes); - fail("Should have thrown an IOException, byte=[" + count4 + "]"); - } catch (final IOException e) { - assertEquals("Read after end of file", e.getMessage()); - } + final IOException e = assertThrows(IOException.class, () -> input.read(bytes)); + assertEquals("Read after end of file", e.getMessage()); // reset by closing input.close(); @@ -214,12 +189,9 @@ public class NullInputStreamTest { assertEquals(7, input.read(), "Read 3"); assertEquals(2, input.skip(5), "Skip 2"); // only 2 left to skip assertEquals(-1, input.skip(5), "Skip 3 (EOF)"); // End of file - try { - input.skip(5); // - fail("Expected IOException for skipping after end of file"); - } catch (final IOException e) { - assertEquals("Skip after end of file", e.getMessage(), "Skip after EOF IOException message"); - } + + final IOException e = assertThrows(IOException.class, () -> input.skip(5), "Expected IOException for skipping after end of file"); + assertEquals("Skip after end of file", e.getMessage(), "Skip after EOF IOException message"); input.close(); } } diff --git a/src/test/java/org/apache/commons/io/input/NullReaderTest.java b/src/test/java/org/apache/commons/io/input/NullReaderTest.java index d2d055fb..236a0f95 100644 --- a/src/test/java/org/apache/commons/io/input/NullReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/NullReaderTest.java @@ -75,12 +75,8 @@ public class NullReaderTest { assertTrue(reader.markSupported(), "Mark Should be Supported"); // No Mark - try { - reader.reset(); - fail("Read limit exceeded, expected IOException "); - } catch (final IOException e) { - assertEquals("No position has been marked", e.getMessage(), "No Mark IOException message"); - } + final IOException resetException = assertThrows(IOException.class, reader::reset); + assertEquals("No position has been marked", resetException.getMessage(), "No Mark IOException message"); for (; position < 3; position++) { assertEquals(position, reader.read(), "Read Before Mark [" + position + "]"); @@ -103,13 +99,9 @@ public class NullReaderTest { } // Reset after read limit passed - try { - reader.reset(); - fail("Read limit exceeded, expected IOException "); - } catch (final IOException e) { - assertEquals("Marked position [" + position + "] is no longer valid - passed the read limit [" + readlimit + "]", e.getMessage(), + final IOException e = assertThrows(IOException.class, reader::reset); + assertEquals("Marked position [" + position + "] is no longer valid - passed the read limit [" + readlimit + "]", e.getMessage(), "Read limit IOException message"); - } } } @@ -211,12 +203,9 @@ public class NullReaderTest { assertEquals(7, reader.read(), "Read 3"); assertEquals(2, reader.skip(5), "Skip 2"); // only 2 left to skip assertEquals(-1, reader.skip(5), "Skip 3 (EOF)"); // End of file - try { - reader.skip(5); // - fail("Expected IOException for skipping after end of file"); - } catch (final IOException e) { - assertEquals("Skip after end of file", e.getMessage(), "Skip after EOF IOException message"); - } + + final IOException e = assertThrows(IOException.class, () -> reader.skip(5)); + assertEquals("Skip after end of file", e.getMessage(), "Skip after EOF IOException message"); } } } diff --git a/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java b/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java index db104daf..7aaaa3d9 100644 --- a/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java @@ -36,12 +36,16 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; +import javax.xml.parsers.DocumentBuilderFactory; + import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; public class ReaderInputStreamTest { @@ -200,6 +204,22 @@ public class ReaderInputStreamTest { } @Test + public void testIo803SAXException() throws IOException { + final StringReader reader = new StringReader(""); + try (final ReaderInputStream inputStream = ReaderInputStream.builder().setCharset(StandardCharsets.UTF_8).setReader(reader).get()) { + final InputSource inputSource = new InputSource(inputStream); + assertThrows(SAXException.class, () -> DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputSource)); + } + } + + @Test + public void testIo803StringReaderSanityCheck() { + final StringReader reader = new StringReader(""); + final InputSource inputSource = new InputSource(reader); + assertThrows(SAXException.class, () -> DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputSource)); + } + + @Test public void testLargeUTF8WithBufferedRead() throws IOException { testWithBufferedRead(LARGE_TEST_STRING, UTF_8); } @@ -209,6 +229,17 @@ public class ReaderInputStreamTest { testWithSingleByteRead(LARGE_TEST_STRING, UTF_8); } + @Test + public void testReadEofTwice() throws IOException { + try (ReaderInputStream reader = ReaderInputStream.builder().setCharset(StandardCharsets.UTF_8).setReader(new StringReader("123")).get()) { + assertEquals('1', reader.read()); + assertEquals('2', reader.read()); + assertEquals('3', reader.read()); + assertEquals(-1, reader.read()); + assertEquals(-1, reader.read()); + } + } + @SuppressWarnings("deprecation") @Test public void testReadZero() throws Exception { diff --git a/src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestParamFile.java b/src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestParamFile.java index f66907b2..71795e09 100644 --- a/src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestParamFile.java +++ b/src/test/java/org/apache/commons/io/input/ReversedLinesFileReaderTestParamFile.java @@ -121,14 +121,19 @@ public class ReversedLinesFileReaderTestParamFile { filePath = Files.copy(filePath, fileSystem.getPath("/" + fileName)); } - // We want to test null Charset in the ReversedLinesFileReaderconstructor. + // We want to test null Charset in the ReversedLinesFileReader constructor. final Charset charset = charsetName != null ? Charset.forName(charsetName) : null; try (ReversedLinesFileReader reversedLinesFileReader = blockSize == null ? new ReversedLinesFileReader(filePath, charset) : new ReversedLinesFileReader(filePath, blockSize, charset)) { testDataIntegrityWithBufferedReader(filePath, fileSystem, charset, reversedLinesFileReader); } - try (ReversedLinesFileReader reversedLinesFileReader = ReversedLinesFileReader.builder().setPath(filePath).setBufferSize(blockSize).setCharset(charset) + // @formatter:off + try (ReversedLinesFileReader reversedLinesFileReader = ReversedLinesFileReader.builder() + .setPath(filePath) + .setBufferSize(blockSize) + .setCharset(charset) .get()) { + // @formatter:on testDataIntegrityWithBufferedReader(filePath, fileSystem, charset, reversedLinesFileReader); } } diff --git a/src/test/java/org/apache/commons/io/input/TaggedInputStreamTest.java b/src/test/java/org/apache/commons/io/input/TaggedInputStreamTest.java index 01fbbb94..a61c0fc8 100644 --- a/src/test/java/org/apache/commons/io/input/TaggedInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/TaggedInputStreamTest.java @@ -18,8 +18,8 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -41,46 +41,22 @@ public class TaggedInputStreamTest { new TaggedInputStream(new BrokenInputStream(exception)); // Test the available() method - try { - stream.available(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(stream.isCauseOf(e)); - try { - stream.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException exceptionAvailable = assertThrows(IOException.class, stream::available); + assertTrue(stream.isCauseOf(exceptionAvailable)); + final IOException exceptionAvailableCause = assertThrows(IOException.class, () -> stream.throwIfCauseOf(exceptionAvailable)); + assertEquals(exception, exceptionAvailableCause); // Test the read() method - try { - stream.read(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(stream.isCauseOf(e)); - try { - stream.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException exceptionRead = assertThrows(IOException.class, stream::read); + assertTrue(stream.isCauseOf(exceptionRead)); + final IOException exceptionReadCause = assertThrows(IOException.class, () -> stream.throwIfCauseOf(exceptionRead)); + assertEquals(exception, exceptionReadCause); // Test the close() method - try { - stream.close(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(stream.isCauseOf(e)); - try { - stream.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException exceptionClose = assertThrows(IOException.class, stream::close); + assertTrue(stream.isCauseOf(exceptionClose)); + final IOException exceptionCloseCause = assertThrows(IOException.class, () -> stream.throwIfCauseOf(exceptionClose)); + assertEquals(exception, exceptionCloseCause); } @Test diff --git a/src/test/java/org/apache/commons/io/input/TaggedReaderTest.java b/src/test/java/org/apache/commons/io/input/TaggedReaderTest.java index 63d23bf8..e5bd83ca 100644 --- a/src/test/java/org/apache/commons/io/input/TaggedReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/TaggedReaderTest.java @@ -18,8 +18,8 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import java.io.IOException; import java.io.Reader; @@ -40,46 +40,22 @@ public class TaggedReaderTest { final TaggedReader reader = new TaggedReader(new BrokenReader(exception)); // Test the ready() method - try { - reader.ready(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(reader.isCauseOf(e)); - try { - reader.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException readyException = assertThrows(IOException.class, reader::ready); + assertTrue(reader.isCauseOf(readyException)); + final IOException rethrownReadyException = assertThrows(IOException.class, () -> reader.throwIfCauseOf(readyException)); + assertEquals(exception, rethrownReadyException); // Test the read() method - try { - reader.read(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(reader.isCauseOf(e)); - try { - reader.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException readException = assertThrows(IOException.class, reader::read); + assertTrue(reader.isCauseOf(readException)); + final IOException rethrownReadException = assertThrows(IOException.class, () -> reader.throwIfCauseOf(readException)); + assertEquals(exception, rethrownReadException); // Test the close() method - try { - reader.close(); - fail("Expected exception not thrown."); - } catch (final IOException e) { - assertTrue(reader.isCauseOf(e)); - try { - reader.throwIfCauseOf(e); - fail("Expected exception not thrown."); - } catch (final IOException e2) { - assertEquals(exception, e2); - } - } + final IOException closeException = assertThrows(IOException.class, reader::close); + assertTrue(reader.isCauseOf(closeException)); + final IOException rethrownCloseException = assertThrows(IOException.class, () -> reader.throwIfCauseOf(closeException)); + assertEquals(exception, rethrownCloseException); } @Test diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java index a6315eba..f0e1f340 100644 --- a/src/test/java/org/apache/commons/io/input/TailerTest.java +++ b/src/test/java/org/apache/commons/io/input/TailerTest.java @@ -266,7 +266,7 @@ public class TailerTest { } @Test - public void testCreaterWithDelayAndFromStartWithReopen() throws Exception { + public void testCreatorWithDelayAndFromStartWithReopen() throws Exception { final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen.txt"); createFile(file, 0); final TestTailerListener listener = new TestTailerListener(1); @@ -326,7 +326,7 @@ public class TailerTest { } /* - * Tests [IO-357][Tailer] InterruptedException while the thead is sleeping is silently ignored. + * Tests [IO-357][Tailer] InterruptedException while the thread is sleeping is silently ignored. */ @Test public void testInterrupt() throws Exception { diff --git a/src/test/java/org/apache/commons/io/input/TeeInputStreamTest.java b/src/test/java/org/apache/commons/io/input/TeeInputStreamTest.java index 4fdf9824..49527a92 100644 --- a/src/test/java/org/apache/commons/io/input/TeeInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/TeeInputStreamTest.java @@ -17,7 +17,7 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -28,6 +28,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import org.apache.commons.io.test.ThrowOnCloseInputStream; import org.apache.commons.io.test.ThrowOnCloseOutputStream; @@ -39,7 +40,7 @@ import org.junit.jupiter.api.Test; */ public class TeeInputStreamTest { - private final String ASCII = "US-ASCII"; + private final String ASCII = StandardCharsets.US_ASCII.name(); private InputStream tee; @@ -66,12 +67,8 @@ public class TeeInputStreamTest { verify(goodIs).close(); final TeeInputStream closingTis = new TeeInputStream(goodIs, badOs, true); - try { - closingTis.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodIs, times(2)).close(); - } + assertThrows(IOException.class, closingTis::close); + verify(goodIs, times(2)).close(); } /** @@ -84,20 +81,12 @@ public class TeeInputStreamTest { final ByteArrayOutputStream goodOs = mock(ByteArrayOutputStream.class); final TeeInputStream nonClosingTis = new TeeInputStream(badIs, goodOs, false); - try { - nonClosingTis.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodOs, never()).close(); - } + assertThrows(IOException.class, nonClosingTis::close); + verify(goodOs, never()).close(); final TeeInputStream closingTis = new TeeInputStream(badIs, goodOs, true); - try { - closingTis.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodOs).close(); - } + assertThrows(IOException.class, closingTis::close); + verify(goodOs).close(); } @Test diff --git a/src/test/java/org/apache/commons/io/input/TeeReaderTest.java b/src/test/java/org/apache/commons/io/input/TeeReaderTest.java index 4b694fcd..c4945258 100644 --- a/src/test/java/org/apache/commons/io/input/TeeReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/TeeReaderTest.java @@ -17,7 +17,7 @@ package org.apache.commons.io.input; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -66,12 +66,8 @@ public class TeeReaderTest { verify(goodR).close(); final TeeReader closingTr = new TeeReader(goodR, badW, true); - try { - closingTr.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodR, times(2)).close(); - } + final IOException e = assertThrows(IOException.class, closingTr::close); + verify(goodR, times(2)).close(); } /** @@ -84,21 +80,12 @@ public class TeeReaderTest { final StringWriter goodW = mock(StringWriter.class); final TeeReader nonClosingTr = new TeeReader(badR, goodW, false); - try { - nonClosingTr.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodW, never()).close(); - } + assertThrows(IOException.class, nonClosingTr::close); + verify(goodW, never()).close(); final TeeReader closingTr = new TeeReader(badR, goodW, true); - try { - closingTr.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - //Assert.assertTrue(goodW.closed); - verify(goodW).close(); - } + assertThrows(IOException.class, closingTr::close); + verify(goodW).close(); } @Test @@ -179,4 +166,4 @@ public class TeeReaderTest { assertEquals("ac", output.toString()); } -}
\ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java index 02951f89..f7fcba81 100644 --- a/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedBufferedInputStreamTest.java @@ -26,6 +26,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -63,7 +64,7 @@ public class UnsynchronizedBufferedInputStreamTest { @BeforeEach protected void setUp() throws IOException { fileName = Files.createTempFile(getClass().getSimpleName(), ".tst"); - Files.write(fileName, DATA.getBytes("UTF-8")); + Files.write(fileName, DATA.getBytes(StandardCharsets.UTF_8)); isFile = Files.newInputStream(fileName); is = new BufferedInputStream(isFile); @@ -87,7 +88,7 @@ public class UnsynchronizedBufferedInputStreamTest { */ @Test public void test_available() throws IOException { - assertTrue(is.available() == DATA.length(), "Returned incorrect number of available bytes"); + assertEquals(DATA.length(), is.available(), "Returned incorrect number of available bytes"); // Test that a closed stream throws an IOE for available() final BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(new byte[] { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' })); @@ -271,7 +272,7 @@ public class UnsynchronizedBufferedInputStreamTest { public void test_read() throws IOException { final InputStreamReader isr = new InputStreamReader(is); final int c = isr.read(); - assertTrue(c == DATA.charAt(0), "read returned incorrect char"); + assertEquals(DATA.charAt(0), c, "read returned incorrect char"); final byte[] bytes = new byte[256]; for (int i = 0; i < 256; i++) { @@ -332,7 +333,7 @@ public class UnsynchronizedBufferedInputStreamTest { })) { bufin.read(); final int result = bufin.read(new byte[2], 0, 2); - assertTrue(result == 1, () -> "Incorrect result: " + result); + assertEquals(1, result, () -> "Incorrect result: " + result); } } @@ -409,11 +410,11 @@ public class UnsynchronizedBufferedInputStreamTest { @Test public void test_reset_scenario1() throws IOException { final byte[] input = "12345678900".getBytes(); - final BufferedInputStream buffis = new BufferedInputStream(new ByteArrayInputStream(input)); - buffis.read(); - buffis.mark(5); - buffis.skip(5); - buffis.reset(); + final BufferedInputStream bufin = new BufferedInputStream(new ByteArrayInputStream(input)); + bufin.read(); + bufin.mark(5); + bufin.skip(5); + bufin.reset(); } /** @@ -424,10 +425,10 @@ public class UnsynchronizedBufferedInputStreamTest { @Test public void test_reset_scenario2() throws IOException { final byte[] input = "12345678900".getBytes(); - final BufferedInputStream buffis = new BufferedInputStream(new ByteArrayInputStream(input)); - buffis.mark(5); - buffis.skip(6); - buffis.reset(); + final BufferedInputStream bufin = new BufferedInputStream(new ByteArrayInputStream(input)); + bufin.mark(5); + bufin.skip(6); + bufin.reset(); } /** diff --git a/src/test/java/org/apache/commons/io/input/UnsynchronizedFilterInputStreamTest.java b/src/test/java/org/apache/commons/io/input/UnsynchronizedFilterInputStreamTest.java index ab4e3d94..e09745a1 100644 --- a/src/test/java/org/apache/commons/io/input/UnsynchronizedFilterInputStreamTest.java +++ b/src/test/java/org/apache/commons/io/input/UnsynchronizedFilterInputStreamTest.java @@ -1,5 +1,6 @@ package org.apache.commons.io.input; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -22,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -56,7 +58,7 @@ public class UnsynchronizedFilterInputStreamTest { @BeforeEach protected void setUp() throws IOException { fileName = Files.createTempFile(getClass().getSimpleName(), ".tst"); - Files.write(fileName, DATA.getBytes("UTF-8")); + Files.write(fileName, DATA.getBytes(StandardCharsets.UTF_8)); is = UnsynchronizedFilterInputStream.builder().setInputStream(Files.newInputStream(fileName)).get(); } @@ -78,7 +80,7 @@ public class UnsynchronizedFilterInputStreamTest { */ @Test public void test_available() throws IOException { - assertTrue(is.available() == DATA.length(), "Returned incorrect number of available bytes"); + assertEquals(DATA.length(), is.available(), "Returned incorrect number of available bytes"); } /** @@ -116,7 +118,7 @@ public class UnsynchronizedFilterInputStreamTest { @Test public void test_read() throws IOException { final int c = is.read(); - assertTrue(c == DATA.charAt(0), "read returned incorrect char"); + assertEquals(DATA.charAt(0), c, "read returned incorrect char"); } /** diff --git a/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java b/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java index 026ea4f0..555cf7ca 100644 --- a/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java +++ b/src/test/java/org/apache/commons/io/input/XmlStreamReaderTest.java @@ -435,10 +435,11 @@ public class XmlStreamReaderTest { @Test @DefaultLocale(language = "tr") public void testLowerCaseEncodingWithTurkishLocale_IO_557() throws Exception { - final String[] encodings = {"iso8859-1", "us-ascii", "utf-8"}; + final String[] encodings = { "iso8859-1", "us-ascii", "utf-8" }; // lower-case for (final String encoding : encodings) { final String xml = getXML("no-bom", XML3, encoding, encoding); - try (ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(encoding)); XmlStreamReader xmlReader = new XmlStreamReader(is)) { + try (ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes(encoding)); + XmlStreamReader xmlReader = new XmlStreamReader(is)) { assertTrue(encoding.equalsIgnoreCase(xmlReader.getEncoding()), "Check encoding : " + encoding); assertEquals(xml, IOUtils.toString(xmlReader), "Check content"); } @@ -529,12 +530,9 @@ public class XmlStreamReaderTest { protected void testRawNoBomInvalid(final String encoding) throws Exception { try (final InputStream is = getXmlInputStream("no-bom", XML3, encoding, encoding)) { - try { - new XmlStreamReader(is, false).close(); - fail("It should have failed"); - } catch (final IOException ex) { - assertTrue(ex.getMessage().contains("Invalid encoding,")); - } + final XmlStreamReader xmlStreamReader = new XmlStreamReader(is, false); + final IOException ex = assertThrows(IOException.class, xmlStreamReader::close); + assertTrue(ex.getMessage().contains("Invalid encoding,")); } } diff --git a/src/test/java/org/apache/commons/io/input/XmlStreamReaderUtilitiesTest.java b/src/test/java/org/apache/commons/io/input/XmlStreamReaderUtilitiesTest.java index 5d80cabc..e2cd2e68 100644 --- a/src/test/java/org/apache/commons/io/input/XmlStreamReaderUtilitiesTest.java +++ b/src/test/java/org/apache/commons/io/input/XmlStreamReaderUtilitiesTest.java @@ -38,7 +38,7 @@ public class XmlStreamReaderUtilitiesTest { } private static final String RAWMGS1 = "encoding mismatch"; private static final String RAWMGS2 = "unknown BOM"; - private static final String HTTPMGS1 = "BOM must be NULL"; + private static final String HTTPMGS1 = "BOM must be null"; private static final String HTTPMGS2 = "encoding mismatch"; private static final String HTTPMGS3 = "Illegal MIME"; @@ -121,7 +121,7 @@ public class XmlStreamReaderUtilitiesTest { builder.append("xmlGuessEnc=[").append(xmlGuessEnc).append("], "); builder.append("xmlEnc=[").append(xmlEnc).append("], "); builder.append("defaultEncoding=[").append(defaultEncoding).append("],"); - final String encoding = calculateRawEncoding(bomEnc,xmlGuessEnc,xmlEnc, defaultEncoding); + final String encoding = calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc, defaultEncoding); assertEquals(expected, encoding, builder.toString()); } diff --git a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java index 928ac115..a8299dc7 100644 --- a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java +++ b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java @@ -104,7 +104,7 @@ public class XmlStreamReader extends Reader { "Illegal encoding, BOM [{0}] XML guess [{1}] XML prolog [{2}] unknown BOM"); private static final MessageFormat HTTP_EX_1 = new MessageFormat( - "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be NULL"); + "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], BOM must be null"); private static final MessageFormat HTTP_EX_2 = new MessageFormat( "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], encoding mismatch"); @@ -112,7 +112,7 @@ public class XmlStreamReader extends Reader { private static final MessageFormat HTTP_EX_3 = new MessageFormat( "Illegal encoding, CT-MIME [{0}] CT-Enc [{1}] BOM [{2}] XML guess [{3}] XML prolog [{4}], Illegal MIME"); - // returns the BOM in the stream, NULL if not present, + // returns the BOM in the stream, null if not present, // if there was BOM the in the stream it is consumed static String getBOMEncoding(final BufferedInputStream is) throws IOException { @@ -141,8 +141,8 @@ public class XmlStreamReader extends Reader { return encoding; } - // returns charset parameter value, NULL if not present, NULL if - // httpContentType is NULL + // returns charset parameter value, null if not present, null if + // httpContentType is null static String getContentTypeEncoding(final String httpContentType) { String encoding = null; if (httpContentType != null) { @@ -157,7 +157,7 @@ public class XmlStreamReader extends Reader { return encoding; } - // returns MIME type or NULL if httpContentType is NULL + // returns MIME type or null if httpContentType is null static String getContentTypeMime(final String httpContentType) { String mime = null; if (httpContentType != null) { @@ -172,7 +172,7 @@ public class XmlStreamReader extends Reader { * Returns the default encoding to use if none is set in HTTP content-type, * XML prolog and the rules based on content-type are not adequate. * <p> - * If it is NULL the content-type based rules are used. + * If it is null the content-type based rules are used. * * @return the default encoding to use. */ @@ -209,7 +209,7 @@ public class XmlStreamReader extends Reader { return encoding; } - // returns the encoding declared in the <?xml encoding=...?>, NULL if none + // returns the encoding declared in the <?xml encoding=...?>, null if none private static String getXmlProlog(final BufferedInputStream is, final String guessedEnc) throws IOException { String encoding = null; @@ -278,9 +278,9 @@ public class XmlStreamReader extends Reader { * Sets the default encoding to use if none is set in HTTP content-type, XML * prolog and the rules based on content-type are not adequate. * <p> - * If it is set to NULL the content-type based rules are used. + * If it is set to null the content-type based rules are used. * <p> - * By default it is NULL. + * By default it is null. * * @param encoding charset encoding to default to. */ diff --git a/src/test/java/org/apache/commons/io/output/ByteArrayOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/ByteArrayOutputStreamTest.java index 7cfcadb6..2d11e58c 100644 --- a/src/test/java/org/apache/commons/io/output/ByteArrayOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/ByteArrayOutputStreamTest.java @@ -229,7 +229,7 @@ public class ByteArrayOutputStreamTest { @ParameterizedTest(name = "[{index}] {0}") @MethodSource("toBufferedInputStreamFunctionFactories") public void testToBufferedInputStream(final String baosName, final IOFunction<InputStream, InputStream> toBufferedInputStreamFunction) throws IOException { - final byte data[] = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; + final byte[] data = {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; try (ByteArrayInputStream bain = new ByteArrayInputStream(data)) { assertEquals(data.length, bain.available()); @@ -271,13 +271,13 @@ public class ByteArrayOutputStreamTest { // Get data before more writes try (InputStream in = baout.toInputStream()) { - byte refData[] = ref.toByteArray(); + byte[] refData = ref.toByteArray(); // Write some more data writeData(baout, ref, new int[] {2, 4, 8, 16}); // Check original data - byte baoutData[] = IOUtils.toByteArray(in); + byte[] baoutData = IOUtils.toByteArray(in); assertEquals(8224, baoutData.length); checkByteArrays(refData, baoutData); @@ -318,7 +318,7 @@ public class ByteArrayOutputStreamTest { // Get data before reset try (InputStream in = baout.toInputStream()) { - byte refData[] = ref.toByteArray(); + byte[] refData = ref.toByteArray(); // Reset and write some new data baout.reset(); @@ -326,7 +326,7 @@ public class ByteArrayOutputStreamTest { writeData(baout, ref, new int[] {2, 4, 8, 16}); // Check original data - byte baoutData[] = IOUtils.toByteArray(in); + byte[] baoutData = IOUtils.toByteArray(in); assertEquals(8224, baoutData.length); checkByteArrays(refData, baoutData); diff --git a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java index 35038d2e..e23a40c0 100644 --- a/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/DeferredFileOutputStreamTest.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.stream.IntStream; import org.apache.commons.io.FileUtils; @@ -80,6 +81,7 @@ public class DeferredFileOutputStreamTest { dfos.close(); assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); + assertEquals(testFile.length(), dfos.getByteCount()); verifyResultFile(testFile); @@ -107,6 +109,7 @@ public class DeferredFileOutputStreamTest { dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertFalse(dfos.isInMemory()); + assertEquals(testFile.length(), dfos.getByteCount()); try (InputStream is = dfos.toInputStream()) { assertArrayEquals(testBytes, IOUtils.toByteArray(is)); @@ -131,6 +134,7 @@ public class DeferredFileOutputStreamTest { dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertTrue(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); final byte[] resultBytes = dfos.getData(); assertEquals(testBytes.length, resultBytes.length); @@ -153,6 +157,7 @@ public class DeferredFileOutputStreamTest { dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertTrue(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); final byte[] resultBytes = dfos.getData(); assertEquals(testBytes.length, resultBytes.length); @@ -175,6 +180,7 @@ public class DeferredFileOutputStreamTest { dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertTrue(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); try (InputStream is = dfos.toInputStream()) { assertArrayEquals(testBytes, IOUtils.toByteArray(is)); @@ -190,7 +196,7 @@ public class DeferredFileOutputStreamTest { final String prefix = "commons-io-test"; final String suffix = ".out"; - final File tempDir = FileUtils.current(); + final Path tempDir = Paths.get("target"); // @formatter:off final DeferredFileOutputStream dfos = DeferredFileOutputStream.builder() .setThreshold(testBytes.length - 5) @@ -198,18 +204,21 @@ public class DeferredFileOutputStreamTest { .setPrefix(prefix) .setSuffix(suffix) .setDirectory(tempDir) + .setDirectory(tempDir.toFile()) .get(); // @formatter:on - assertNull(dfos.getFile(), "Check file is null-A"); + assertNull(dfos.getFile(), "Check File is null-A"); + assertNull(dfos.getPath(), "Check Path is null-A"); dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertFalse(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); assertNull(dfos.getData()); assertNotNull(dfos.getFile(), "Check file not null"); assertTrue(dfos.getFile().exists(), "Check file exists"); assertTrue(dfos.getFile().getName().startsWith(prefix), "Check prefix"); assertTrue(dfos.getFile().getName().endsWith(suffix), "Check suffix"); - assertEquals(tempDir.getPath(), dfos.getFile().getParent(), "Check dir"); + assertEquals(tempDir, dfos.getPath().getParent(), "Check dir"); verifyResultFile(dfos.getFile()); @@ -227,7 +236,7 @@ public class DeferredFileOutputStreamTest { final String prefix = "commons-io-test"; final String suffix = null; - final File tempDir = null; + final Path tempDir = null; // @formatter:off final DeferredFileOutputStream dfos = DeferredFileOutputStream.builder() .setThreshold(testBytes.length - 5) @@ -237,11 +246,13 @@ public class DeferredFileOutputStreamTest { .setDirectory(tempDir) .get(); // @formatter:on - assertNull(dfos.getFile(), "Check file is null-A"); + assertNull(dfos.getFile(), "Check File is null-A"); + assertNull(dfos.getPath(), "Check Path is null-A"); dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); + assertEquals(testBytes.length, dfos.getByteCount()); assertNotNull(dfos.getFile(), "Check file not null"); assertTrue(dfos.getFile().exists(), "Check file exists"); assertTrue(dfos.getFile().getName().startsWith(prefix), "Check prefix"); @@ -265,10 +276,12 @@ public class DeferredFileOutputStreamTest { final String suffix = ".out"; final File tempDir = FileUtils.current(); final DeferredFileOutputStream dfos = new DeferredFileOutputStream(testBytes.length + 42, initialBufferSize, prefix, suffix, tempDir); - assertNull(dfos.getFile(), "Check file is null-A"); + assertNull(dfos.getFile(), "Check File is null-A"); + assertNull(dfos.getPath(), "Check Path is null-A"); dfos.write(testBytes, 0, testBytes.length); dfos.close(); assertTrue(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); assertNull(dfos.getFile(), "Check file is null-B"); } @@ -312,6 +325,7 @@ public class DeferredFileOutputStreamTest { dfos.close(); assertFalse(dfos.isInMemory()); assertNull(dfos.getData()); + assertEquals(testBytes.length, dfos.getByteCount()); verifyResultFile(testFile); @@ -335,6 +349,7 @@ public class DeferredFileOutputStreamTest { assertTrue(testFile.exists()); assertFalse(dfos.isInMemory()); + assertEquals(testBytes.length, dfos.getByteCount()); assertThrows(IOException.class, () -> dfos.writeTo(baos)); @@ -364,6 +379,7 @@ public class DeferredFileOutputStreamTest { assertFalse(dfos.isInMemory()); assertThrows(IOException.class, () -> dfos.writeTo(baos)); + assertEquals(testBytes.length, dfos.getByteCount()); dfos.close(); dfos.writeTo(baos); @@ -392,6 +408,7 @@ public class DeferredFileOutputStreamTest { assertTrue(dfos.isInMemory()); assertThrows(IOException.class, () -> dfos.writeTo(baos)); + assertEquals(testBytes.length, dfos.getByteCount()); dfos.close(); dfos.writeTo(baos); diff --git a/src/test/java/org/apache/commons/io/output/TeeOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/TeeOutputStreamTest.java index 1cfa7b12..00b0a924 100644 --- a/src/test/java/org/apache/commons/io/output/TeeOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/TeeOutputStreamTest.java @@ -17,7 +17,7 @@ package org.apache.commons.io.output; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -49,12 +49,9 @@ public class TeeOutputStreamTest { final OutputStream badOs = new ThrowOnCloseOutputStream(); final ByteArrayOutputStream goodOs = mock(ByteArrayOutputStream.class); final TeeOutputStream tos = new TeeOutputStream(badOs, goodOs); - try { - tos.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodOs).close(); - } + + assertThrows(IOException.class, tos::close); + verify(goodOs).close(); } /** @@ -66,12 +63,9 @@ public class TeeOutputStreamTest { final OutputStream badOs = new ThrowOnCloseOutputStream(); final ByteArrayOutputStream goodOs = mock(ByteArrayOutputStream.class); final TeeOutputStream tos = new TeeOutputStream(goodOs, badOs); - try { - tos.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOException e) { - verify(goodOs).close(); - } + + assertThrows(IOException.class, tos::close); + verify(goodOs).close(); } @Test diff --git a/src/test/java/org/apache/commons/io/output/TeeWriterTest.java b/src/test/java/org/apache/commons/io/output/TeeWriterTest.java index 0b5af708..8f0f8ee7 100644 --- a/src/test/java/org/apache/commons/io/output/TeeWriterTest.java +++ b/src/test/java/org/apache/commons/io/output/TeeWriterTest.java @@ -17,8 +17,8 @@ package org.apache.commons.io.output; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -39,99 +39,81 @@ import org.junit.jupiter.api.Test; public class TeeWriterTest { @Test - public void testArrayIOExceptionOnAppendChar1() throws IOException { + public void testArrayIOExceptionOnAppendChar1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null); final char data = 'A'; - try { - tw.append(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data)); + verify(goodW).append(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnAppendChar2() throws IOException { + public void testArrayIOExceptionOnAppendChar2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null); final char data = 'A'; - try { - tw.append(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data)); + verify(goodW).append(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnAppendCharSequence1() throws IOException { + public void testArrayIOExceptionOnAppendCharSequence1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final String data = "A"; - try { - tw.append(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data)); + verify(goodW).append(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnAppendCharSequence2() throws IOException { + public void testArrayIOExceptionOnAppendCharSequence2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final String data = "A"; - try { - tw.append(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data)); + verify(goodW).append(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnAppendCharSequenceIntInt1() throws IOException { + public void testArrayIOExceptionOnAppendCharSequenceIntInt1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final String data = "A"; - try { - tw.append(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data, 0, 0)); + verify(goodW).append(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnAppendCharSequenceIntInt2() throws IOException { + public void testArrayIOExceptionOnAppendCharSequenceIntInt2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final String data = "A"; - try { - tw.append(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).append(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.append(data, 0, 0)); + verify(goodW).append(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test @@ -139,14 +121,11 @@ public class TeeWriterTest { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); - try { - tw.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).close(); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, tw::close); + verify(goodW).close(); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test @@ -154,44 +133,35 @@ public class TeeWriterTest { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); - try { - tw.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).close(); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, tw::close); + verify(goodW).close(); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnFlush1() throws IOException { + public void testArrayIOExceptionOnFlush1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); - try { - tw.flush(); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).flush(); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, tw::flush); + verify(goodW).flush(); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnFlush2() throws IOException { + public void testArrayIOExceptionOnFlush2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); - try { - tw.flush(); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).flush(); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, tw::flush); + verify(goodW).flush(); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test @@ -200,14 +170,11 @@ public class TeeWriterTest { final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final char[] data = { 'a' }; - try { - tw.write(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data)); + verify(goodW).write(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test @@ -216,144 +183,114 @@ public class TeeWriterTest { final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final char[] data = { 'a' }; - try { - tw.write(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data)); + verify(goodW).write(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteCharArrayIntInt1() throws IOException { + public void testArrayIOExceptionOnWriteCharArrayIntInt1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final char[] data = { 'a' }; - try { - tw.write(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data, 0, 0)); + verify(goodW).write(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteCharArrayIntInt2() throws IOException { + public void testArrayIOExceptionOnWriteCharArrayIntInt2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final char[] data = { 'a' }; - try { - tw.write(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data, 0, 0)); + verify(goodW).write(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteInt1() throws IOException { + public void testArrayIOExceptionOnWriteInt1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final int data = 32; - try { - tw.write(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data)); + verify(goodW).write(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteInt2() throws IOException { + public void testArrayIOExceptionOnWriteInt2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); - try { - tw.write(32); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(32); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(32)); + verify(goodW).write(32); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteString1() throws IOException { + public void testArrayIOExceptionOnWriteString1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final String data = "A"; - try { - tw.write(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data)); + verify(goodW).write(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteString2() throws IOException { + public void testArrayIOExceptionOnWriteString2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final String data = "A"; - try { - tw.write(data); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data)); + verify(goodW).write(data); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteStringIntInt1() throws IOException { + public void testArrayIOExceptionOnWriteStringIntInt1() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(badW, goodW, null); final String data = "A"; - try { - tw.write(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); - } + + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data, 0, 0)); + verify(goodW).write(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex()); } @Test - public void testArrayIOExceptionOnWriteStringIntInt2() throws IOException { + public void testArrayIOExceptionOnWriteStringIntInt2() { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(goodW, badW, null); final String data = "A"; - try { - tw.write(data, 0, 0); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).write(data, 0, 0); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + final IOExceptionList e = assertThrows(IOExceptionList.class, () -> tw.write(data, 0, 0)); + verify(goodW).write(data, 0, 0); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test @@ -361,15 +298,11 @@ public class TeeWriterTest { final Writer badW = BrokenWriter.INSTANCE; final StringWriter goodW = mock(StringWriter.class); final TeeWriter tw = new TeeWriter(Arrays.asList(goodW, badW, null)); - try { - tw.close(); - fail("Expected " + IOException.class.getName()); - } catch (final IOExceptionList e) { - verify(goodW).close(); - assertEquals(1, e.getCauseList().size()); - assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); - } + final IOExceptionList e = assertThrows(IOExceptionList.class, tw::close); + verify(goodW).close(); + assertEquals(1, e.getCauseList().size()); + assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex()); } @Test diff --git a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java index b342d28c..dd1299e0 100644 --- a/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java +++ b/src/test/java/org/apache/commons/io/output/ThresholdingOutputStreamTest.java @@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test; public class ThresholdingOutputStreamTest { @Test - public void testSetByteCount() throws Exception { + public void testSetByteCount_Stream() throws Exception { final AtomicBoolean reached = new AtomicBoolean(false); try (ThresholdingOutputStream tos = new ThresholdingOutputStream(3) { { @@ -58,6 +58,31 @@ public class ThresholdingOutputStreamTest { } @Test + public void testSetByteCount_OutputStream() throws Exception { + final AtomicBoolean reached = new AtomicBoolean(false); + try (ThresholdingOutputStream tos = new ThresholdingOutputStream(3) { + { + setByteCount(2); + } + + @Override + protected OutputStream getOutputStream() throws IOException { + return new ByteArrayOutputStream(4); + } + + @Override + protected void thresholdReached() throws IOException { + reached.set(true); + } + }) { + tos.write('a'); + assertFalse(reached.get()); + tos.write('a'); + assertTrue(reached.get()); + } + } + + @Test public void testThresholdIOConsumer() throws Exception { final AtomicBoolean reached = new AtomicBoolean(); // Null threshold consumer diff --git a/src/test/java/org/apache/commons/io/output/UncheckedAppendableTest.java b/src/test/java/org/apache/commons/io/output/UncheckedAppendableTest.java index 75a64373..e22f85d5 100644 --- a/src/test/java/org/apache/commons/io/output/UncheckedAppendableTest.java +++ b/src/test/java/org/apache/commons/io/output/UncheckedAppendableTest.java @@ -17,7 +17,7 @@ package org.apache.commons.io.output; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.io.StringWriter; @@ -64,32 +64,20 @@ public class UncheckedAppendableTest { @Test public void testAppendCharSequenceIndexedThrows() { - try { - appendableBroken.append("a", 0, 1); - fail("Expected exception not thrown."); - } catch (final UncheckedIOException e) { - assertEquals(exception, e.getCause()); - } + final UncheckedIOException e = assertThrows(UncheckedIOException.class, () -> appendableBroken.append("a", 0, 1)); + assertEquals(exception, e.getCause()); } @Test public void testAppendCharSequenceThrows() { - try { - appendableBroken.append("a"); - fail("Expected exception not thrown."); - } catch (final UncheckedIOException e) { - assertEquals(exception, e.getCause()); - } + final UncheckedIOException e = assertThrows(UncheckedIOException.class, () -> appendableBroken.append("a")); + assertEquals(exception, e.getCause()); } @Test public void testAppendCharThrows() { - try { - appendableBroken.append('a'); - fail("Expected exception not thrown."); - } catch (final UncheckedIOException e) { - assertEquals(exception, e.getCause()); - } + final UncheckedIOException e2 = assertThrows(UncheckedIOException.class, () -> appendableBroken.append('a')); + assertEquals(exception, e2.getCause()); } @Test diff --git a/src/test/java/org/apache/commons/io/serialization/MockSerializedClass.java b/src/test/java/org/apache/commons/io/serialization/MockSerializedClass.java index 726dc705..8e0cb826 100644 --- a/src/test/java/org/apache/commons/io/serialization/MockSerializedClass.java +++ b/src/test/java/org/apache/commons/io/serialization/MockSerializedClass.java @@ -31,7 +31,7 @@ public class MockSerializedClass implements Serializable { @Override public boolean equals(final Object obj) { - if(!(obj instanceof MockSerializedClass)) { + if (!(obj instanceof MockSerializedClass)) { return false; } return str.equals(((MockSerializedClass)obj).str); diff --git a/src/test/java/org/apache/commons/io/test/TestUtils.java b/src/test/java/org/apache/commons/io/test/TestUtils.java index 8ace275e..0620603d 100644 --- a/src/test/java/org/apache/commons/io/test/TestUtils.java +++ b/src/test/java/org/apache/commons/io/test/TestUtils.java @@ -132,7 +132,7 @@ public abstract class TestUtils { while (-1 != n0) { n0 = is0.read(buf0); n1 = is1.read(buf1); - assertTrue(n0 == n1, + assertEquals(n0, n1, "The files " + f0 + " and " + f1 + " have differing number of bytes available (" + n0 + " vs " + n1 + ")"); @@ -164,14 +164,20 @@ public abstract class TestUtils { } } - public static void createFile(final File file, final long size) - throws IOException { + public static void createFile(final File file, final long size) throws IOException { if (!file.getParentFile().exists()) { - throw new IOException("Cannot create file " + file - + " as the parent directory does not exist"); + throw new IOException("Cannot create file " + file + " as the parent directory does not exist"); + } + try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) { + generateTestData(output, size); + } + } + + public static void createFile(final Path file, final long size) throws IOException { + if (!Files.exists(file.getParent())) { + throw new IOException("Cannot create file " + file + " as the parent directory does not exist"); } - try (BufferedOutputStream output = - new BufferedOutputStream(Files.newOutputStream(file.toPath()))) { + try (BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file))) { generateTestData(output, size); } } diff --git a/src/test/resources/org/apache/commons/io/TIKA-4065.bin b/src/test/resources/org/apache/commons/io/TIKA-4065.bin Binary files differnew file mode 100644 index 00000000..1803df9d --- /dev/null +++ b/src/test/resources/org/apache/commons/io/TIKA-4065.bin |