Index: 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java (.../ByteOrderMark.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderMark.java (.../ByteOrderMark.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -17,10 +17,26 @@
package org.apache.commons.io;
import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
import java.util.Locale;
+import java.util.Objects;
/**
- * Byte Order Mark (BOM) representation - see {@link org.apache.commons.io.input.BOMInputStream}.
+ * Byte Order Mark (BOM) representation. See {@link org.apache.commons.io.input.BOMInputStream}.
+ *
+ * We define the follow BOM constants:
+ *
+ *
+ *
{@link #UTF_16BE}
+ *
{@link #UTF_16LE}
+ *
{@link #UTF_32BE}
+ *
{@link #UTF_32LE}
+ *
{@link #UTF_8}
+ *
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @see org.apache.commons.io.input.BOMInputStream
* @see Wikipedia: Byte Order Mark
@@ -32,24 +48,60 @@
private static final long serialVersionUID = 1L;
- /** UTF-8 BOM. */
- public static final ByteOrderMark UTF_8 = new ByteOrderMark("UTF-8", 0xEF, 0xBB, 0xBF);
+ /**
+ * UTF-8 BOM.
+ *
+ * This BOM is:
+ *
+ *
+ * 0xEF 0xBB 0xBF
+ *
+ */
+ public static final ByteOrderMark UTF_8 = new ByteOrderMark(StandardCharsets.UTF_8.name(), 0xEF, 0xBB, 0xBF);
- /** UTF-16BE BOM (Big-Endian). */
- public static final ByteOrderMark UTF_16BE = new ByteOrderMark("UTF-16BE", 0xFE, 0xFF);
+ /**
+ * UTF-16BE BOM (Big-Endian).
+ *
+ * This BOM is:
+ *
+ *
+ * 0xFE 0xFF
+ *
+ */
+ public static final ByteOrderMark UTF_16BE = new ByteOrderMark(StandardCharsets.UTF_16BE.name(), 0xFE, 0xFF);
- /** UTF-16LE BOM (Little-Endian). */
- public static final ByteOrderMark UTF_16LE = new ByteOrderMark("UTF-16LE", 0xFF, 0xFE);
+ /**
+ * UTF-16LE BOM (Little-Endian).
+ *
+ * This BOM is:
+ *
+ *
+ * 0xFF 0xFE
+ *
+ */
+ public static final ByteOrderMark UTF_16LE = new ByteOrderMark(StandardCharsets.UTF_16LE.name(), 0xFF, 0xFE);
/**
* UTF-32BE BOM (Big-Endian).
+ *
+ * This BOM is:
+ *
+ *
+ * 0x00 0x00 0xFE 0xFF
+ *
*
* @since 2.2
*/
public static final ByteOrderMark UTF_32BE = new ByteOrderMark("UTF-32BE", 0x00, 0x00, 0xFE, 0xFF);
/**
* UTF-32LE BOM (Little-Endian).
+ *
+ * This BOM is:
+ *
+ *
+ * 0xFF 0xFE 0x00 0x00
+ *
*
* @since 2.2
*/
@@ -63,50 +115,62 @@
*/
public static final char UTF_BOM = '\uFEFF';
+ /**
+ * Charset name.
+ */
private final String charsetName;
+
+ /**
+ * Bytes.
+ */
private final int[] bytes;
/**
- * Constructs a new BOM.
+ * Constructs a new instance.
*
* @param charsetName The name of the charset the BOM represents
* @param bytes The BOM's bytes
- * @throws IllegalArgumentException if the charsetName is null or
- * zero length
- * @throws IllegalArgumentException if the bytes are null or zero
- * length
+ * @throws IllegalArgumentException if the charsetName is zero length
+ * @throws IllegalArgumentException if the bytes are zero length
*/
public ByteOrderMark(final String charsetName, final int... bytes) {
- if (charsetName == null || charsetName.isEmpty()) {
+ Objects.requireNonNull(charsetName, "charsetName");
+ Objects.requireNonNull(bytes, "bytes");
+ if (charsetName.isEmpty()) {
throw new IllegalArgumentException("No charsetName specified");
}
- if (bytes == null || bytes.length == 0) {
+ if (bytes.length == 0) {
throw new IllegalArgumentException("No bytes specified");
}
this.charsetName = charsetName;
- this.bytes = new int[bytes.length];
- System.arraycopy(bytes, 0, this.bytes, 0, bytes.length);
+ this.bytes = bytes.clone();
}
/**
- * Gets the name of the {@link java.nio.charset.Charset} the BOM represents.
+ * Indicates if this instance's bytes equals another.
*
- * @return the character set name
+ * @param obj The object to compare to
+ * @return true if the bom's bytes are equal, otherwise
+ * false
*/
- public String getCharsetName() {
- return charsetName;
+ @Override
+ public boolean equals(final Object obj) {
+ if (!(obj instanceof ByteOrderMark)) {
+ return false;
+ }
+ final ByteOrderMark bom = (ByteOrderMark) obj;
+ if (bytes.length != bom.length()) {
+ return false;
+ }
+ for (int i = 0; i < bytes.length; i++) {
+ if (bytes[i] != bom.get(i)) {
+ return false;
+ }
+ }
+ return true;
}
/**
- * Gets the length of the BOM's bytes.
- *
- * @return the length of the BOM's bytes
- */
- public int length() {
- return bytes.length;
- }
-
- /**
* Gets the byte at the specified position.
*
* @param pos The position
@@ -124,40 +188,25 @@
public byte[] getBytes() {
final byte[] copy = IOUtils.byteArray(bytes.length);
for (int i = 0; i < bytes.length; i++) {
- copy[i] = (byte)bytes[i];
+ copy[i] = (byte) bytes[i];
}
return copy;
}
/**
- * Indicates if this BOM's bytes equals another.
+ * Gets the name of the {@link java.nio.charset.Charset} the BOM represents.
*
- * @param obj The object to compare to
- * @return true if the bom's bytes are equal, otherwise
- * false
+ * @return the character set name
*/
- @Override
- public boolean equals(final Object obj) {
- if (!(obj instanceof ByteOrderMark)) {
- return false;
- }
- final ByteOrderMark bom = (ByteOrderMark)obj;
- if (bytes.length != bom.length()) {
- return false;
- }
- for (int i = 0; i < bytes.length; i++) {
- if (bytes[i] != bom.get(i)) {
- return false;
- }
- }
- return true;
+ public String getCharsetName() {
+ return charsetName;
}
/**
- * Computes the hashcode for this BOM.
+ * Computes the hash code for this BOM.
*
- * @return the hashcode for this BOM.
- * @see java.lang.Object#hashCode()
+ * @return the hash code for this BOM.
+ * @see Object#hashCode()
*/
@Override
public int hashCode() {
@@ -169,6 +218,15 @@
}
/**
+ * Gets the length of the BOM's bytes.
+ *
+ * @return the length of the BOM's bytes
+ */
+ public int length() {
+ return bytes.length;
+ }
+
+ /**
* Converts this instance to a String representation of the BOM.
*
* @return the length of the BOM's bytes
Index: 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderParser.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderParser.java (.../ByteOrderParser.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/ByteOrderParser.java (.../ByteOrderParser.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -27,12 +27,6 @@
public final class ByteOrderParser {
/**
- * ByteOrderUtils is a static utility class, so prevent construction with a private constructor.
- */
- private ByteOrderParser() {
- }
-
- /**
* Parses the String argument as a {@link ByteOrder}.
*
* Returns {@code ByteOrder.LITTLE_ENDIAN} if the given value is {@code "LITTLE_ENDIAN"}.
@@ -47,10 +41,10 @@
*
*
* @param value
- * the {@code String} containing the ByteOrder representation to be parsed
+ * the {@link String} containing the ByteOrder representation to be parsed
* @return the ByteOrder represented by the string argument
* @throws IllegalArgumentException
- * if the {@code String} containing the ByteOrder representation to be parsed is unknown.
+ * if the {@link String} containing the ByteOrder representation to be parsed is unknown.
*/
public static ByteOrder parseByteOrder(final String value) {
if (ByteOrder.BIG_ENDIAN.toString().equals(value)) {
@@ -63,4 +57,10 @@
", " + ByteOrder.BIG_ENDIAN);
}
+ /**
+ * ByteOrderUtils is a static utility class, so prevent construction with a private constructor.
+ */
+ private ByteOrderParser() {
+ }
+
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/Charsets.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/Charsets.java (.../Charsets.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/Charsets.java (.../Charsets.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -26,7 +26,7 @@
/**
* Charsets required of every implementation of the Java platform.
*
- * From the Java documentation
+ * From the Java documentation
* Standard charsets:
*
* Every implementation of the Java platform is required to support the following character encodings. Consult
@@ -50,7 +50,7 @@
* accepted on input, big-endian used on output.)
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @since 2.3
*/
public class Charsets {
@@ -74,50 +74,12 @@
}
/**
- * Constructs a sorted map from canonical charset names to charset objects required of every implementation of the
- * Java platform.
- *
- *
- * @return An immutable, case-insensitive map from canonical charset names to charset objects.
- * @see Charset#availableCharsets()
- * @since 2.5
- */
- public static SortedMap requiredCharsets() {
- return STANDARD_CHARSET_MAP;
- }
-
- /**
- * Returns the given Charset or the default Charset if the given Charset is null.
- *
- * @param charset
- * A charset or null.
- * @return the given Charset or the default Charset if the given Charset is null
- */
- public static Charset toCharset(final Charset charset) {
- return charset == null ? Charset.defaultCharset() : charset;
- }
-
- /**
- * Returns a Charset for the named charset. If the name is null, return the default Charset.
- *
- * @param charsetName The name of the requested charset, may be null.
- * @return a Charset for the named charset.
- * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
- */
- public static Charset toCharset(final String charsetName) throws UnsupportedCharsetException {
- return charsetName == null ? Charset.defaultCharset() : Charset.forName(charsetName);
- }
-
- /**
* CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.
*
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
@@ -131,7 +93,7 @@
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
@@ -146,7 +108,7 @@
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
@@ -160,7 +122,7 @@
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
@@ -174,7 +136,7 @@
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
@@ -188,9 +150,72 @@
* Every implementation of the Java platform is required to support this character encoding.
*
*
- * @see Standard charsets
+ * @see Standard charsets
* @deprecated Use Java 7's {@link java.nio.charset.StandardCharsets}
*/
@Deprecated
public static final Charset UTF_8 = StandardCharsets.UTF_8;
+
+ /**
+ * Constructs a sorted map from canonical charset names to charset objects required of every implementation of the
+ * Java platform.
+ *
+ *
+ * @return An immutable, case-insensitive map from canonical charset names to charset objects.
+ * @see Charset#availableCharsets()
+ * @since 2.5
+ */
+ public static SortedMap requiredCharsets() {
+ return STANDARD_CHARSET_MAP;
+ }
+
+ /**
+ * Returns the given Charset or the default Charset if the given Charset is null.
+ *
+ * @param charset
+ * A charset or null.
+ * @return the given Charset or the default Charset if the given Charset is null
+ */
+ public static Charset toCharset(final Charset charset) {
+ return charset == null ? Charset.defaultCharset() : charset;
+ }
+
+ /**
+ * Returns the given charset if non-null, otherwise return defaultCharset.
+ *
+ * @param charset The charset to test, may be null.
+ * @param defaultCharset The charset to return if charset is null, may be null.
+ * @return a Charset .
+ * @since 2.12.0
+ */
+ public static Charset toCharset(final Charset charset, final Charset defaultCharset) {
+ return charset == null ? defaultCharset : charset;
+ }
+
+ /**
+ * Returns a Charset for the named charset. If the name is null, return the default Charset.
+ *
+ * @param charsetName The name of the requested charset, may be null.
+ * @return a Charset for the named charset.
+ * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
+ */
+ public static Charset toCharset(final String charsetName) throws UnsupportedCharsetException {
+ return toCharset(charsetName, Charset.defaultCharset());
+ }
+
+ /**
+ * Returns a Charset for the named charset. If the name is null, return the given default Charset.
+ *
+ * @param charsetName The name of the requested charset, may be null.
+ * @param defaultCharset The name charset to return if charsetName is null, may be null.
+ * @return a Charset for the named charset.
+ * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
+ * @since 2.12.0
+ */
+ public static Charset toCharset(final String charsetName, final Charset defaultCharset) throws UnsupportedCharsetException {
+ return charsetName == null ? defaultCharset : Charset.forName(charsetName);
+ }
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/CloseableURLConnection.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/CloseableURLConnection.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/CloseableURLConnection.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,275 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Delegates to a URLConnection while implementing AutoCloseable.
+ */
+final class CloseableURLConnection extends URLConnection implements AutoCloseable {
+
+ static CloseableURLConnection open(final URI uri) throws IOException {
+ return open(Objects.requireNonNull(uri, "uri").toURL());
+ }
+
+ static CloseableURLConnection open(final URL url) throws IOException {
+ return new CloseableURLConnection(url.openConnection());
+ }
+
+ private final URLConnection urlConnection;
+
+ CloseableURLConnection(final URLConnection urlConnection) {
+ super(Objects.requireNonNull(urlConnection, "urlConnection").getURL());
+ this.urlConnection = urlConnection;
+ }
+
+ @Override
+ public void addRequestProperty(final String key, final String value) {
+ urlConnection.addRequestProperty(key, value);
+ }
+
+ @Override
+ public void close() {
+ IOUtils.close(urlConnection);
+ }
+
+ @Override
+ public void connect() throws IOException {
+ urlConnection.connect();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ return urlConnection.equals(obj);
+ }
+
+ @Override
+ public boolean getAllowUserInteraction() {
+ return urlConnection.getAllowUserInteraction();
+ }
+
+ @Override
+ public int getConnectTimeout() {
+ return urlConnection.getConnectTimeout();
+ }
+
+ @Override
+ public Object getContent() throws IOException {
+ return urlConnection.getContent();
+ }
+
+ @Override
+ public Object getContent(@SuppressWarnings("rawtypes") final Class[] classes) throws IOException {
+ return urlConnection.getContent(classes);
+ }
+
+ @Override
+ public String getContentEncoding() {
+ return urlConnection.getContentEncoding();
+ }
+
+ @Override
+ public int getContentLength() {
+ return urlConnection.getContentLength();
+ }
+
+ @Override
+ public long getContentLengthLong() {
+ return urlConnection.getContentLengthLong();
+ }
+
+ @Override
+ public String getContentType() {
+ return urlConnection.getContentType();
+ }
+
+ @Override
+ public long getDate() {
+ return urlConnection.getDate();
+ }
+
+ @Override
+ public boolean getDefaultUseCaches() {
+ return urlConnection.getDefaultUseCaches();
+ }
+
+ @Override
+ public boolean getDoInput() {
+ return urlConnection.getDoInput();
+ }
+
+ @Override
+ public boolean getDoOutput() {
+ return urlConnection.getDoOutput();
+ }
+
+ @Override
+ public long getExpiration() {
+ return urlConnection.getExpiration();
+ }
+
+ @Override
+ public String getHeaderField(final int n) {
+ return urlConnection.getHeaderField(n);
+ }
+
+ @Override
+ public String getHeaderField(final String name) {
+ return urlConnection.getHeaderField(name);
+ }
+
+ @Override
+ public long getHeaderFieldDate(final String name, final long Default) {
+ return urlConnection.getHeaderFieldDate(name, Default);
+ }
+
+ @Override
+ public int getHeaderFieldInt(final String name, final int Default) {
+ return urlConnection.getHeaderFieldInt(name, Default);
+ }
+
+ @Override
+ public String getHeaderFieldKey(final int n) {
+ return urlConnection.getHeaderFieldKey(n);
+ }
+
+ @Override
+ public long getHeaderFieldLong(final String name, final long Default) {
+ return urlConnection.getHeaderFieldLong(name, Default);
+ }
+
+ @Override
+ public Map> getHeaderFields() {
+ return urlConnection.getHeaderFields();
+ }
+
+ @Override
+ public long getIfModifiedSince() {
+ return urlConnection.getIfModifiedSince();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return urlConnection.getInputStream();
+ }
+
+ @Override
+ public long getLastModified() {
+ return urlConnection.getLastModified();
+ }
+
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ return urlConnection.getOutputStream();
+ }
+
+ @Override
+ public Permission getPermission() throws IOException {
+ return urlConnection.getPermission();
+ }
+
+ @Override
+ public int getReadTimeout() {
+ return urlConnection.getReadTimeout();
+ }
+
+ @Override
+ public Map> getRequestProperties() {
+ return urlConnection.getRequestProperties();
+ }
+
+ @Override
+ public String getRequestProperty(final String key) {
+ return urlConnection.getRequestProperty(key);
+ }
+
+ @Override
+ public URL getURL() {
+ return urlConnection.getURL();
+ }
+
+ @Override
+ public boolean getUseCaches() {
+ return urlConnection.getUseCaches();
+ }
+
+ @Override
+ public int hashCode() {
+ return urlConnection.hashCode();
+ }
+
+ @Override
+ public void setAllowUserInteraction(final boolean allowUserInteraction) {
+ urlConnection.setAllowUserInteraction(allowUserInteraction);
+ }
+
+ @Override
+ public void setConnectTimeout(final int timeout) {
+ urlConnection.setConnectTimeout(timeout);
+ }
+
+ @Override
+ public void setDefaultUseCaches(final boolean defaultUseCaches) {
+ urlConnection.setDefaultUseCaches(defaultUseCaches);
+ }
+
+ @Override
+ public void setDoInput(final boolean doInput) {
+ urlConnection.setDoInput(doInput);
+ }
+
+ @Override
+ public void setDoOutput(final boolean doOutput) {
+ urlConnection.setDoOutput(doOutput);
+ }
+
+ @Override
+ public void setIfModifiedSince(final long ifModifiedSince) {
+ urlConnection.setIfModifiedSince(ifModifiedSince);
+ }
+
+ @Override
+ public void setReadTimeout(final int timeout) {
+ urlConnection.setReadTimeout(timeout);
+ }
+
+ @Override
+ public void setRequestProperty(final String key, final String value) {
+ urlConnection.setRequestProperty(key, value);
+ }
+
+ @Override
+ public void setUseCaches(final boolean useCaches) {
+ urlConnection.setUseCaches(useCaches);
+ }
+
+ @Override
+ public String toString() {
+ return urlConnection.toString();
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java (.../CopyUtils.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/CopyUtils.java (.../CopyUtils.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -31,9 +31,9 @@
/**
* This class provides static utility methods for buffered
- * copying between sources ({@code InputStream}, {@code Reader},
- * {@code String} and {@code byte[]}) and destinations
- * ({@code OutputStream}, {@code Writer}, {@code String} and
+ * copying between sources ({@link InputStream}, {@link Reader},
+ * {@link String} and {@code byte[]}) and destinations
+ * ({@link OutputStream}, {@link Writer}, {@link String} and
* {@code byte[]}).
*
* Unless otherwise noted, these {@code copy} methods do not
@@ -103,7 +103,7 @@
* method variants to specify the encoding, each row may
* correspond to up to 2 methods.
*
- * Origin of code: Excalibur.
+ * Provenance: Excalibur.
*
* @deprecated Use IOUtils. Will be removed in 3.0.
* Methods renamed to IOUtils.write() or IOUtils.copy().
@@ -114,14 +114,9 @@
public class CopyUtils {
/**
- * Instances should NOT be constructed in standard programming.
- */
- public CopyUtils() { }
-
- /**
- * Copies bytes from a {@code byte[]} to an {@code OutputStream}.
+ * Copies bytes from a {@code byte[]} to an {@link OutputStream}.
* @param input the byte array to read from
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @throws IOException In case of an I/O problem
*/
public static void copy(final byte[] input, final OutputStream output) throws IOException {
@@ -130,10 +125,11 @@
/**
* Copies and convert bytes from a {@code byte[]} to chars on a
- * {@code Writer}.
+ * {@link Writer}.
* The platform's default encoding is used for the byte-to-char conversion.
+ *
* @param input the byte array to read from
- * @param output the {@code Writer} to write to
+ * @param output the {@link Writer} to write to
* @throws IOException In case of an I/O problem
* @deprecated 2.5 use {@link #copy(byte[], Writer, String)} instead
*/
@@ -145,9 +141,10 @@
/**
* Copies and convert bytes from a {@code byte[]} to chars on a
- * {@code Writer}, using the specified encoding.
+ * {@link Writer}, using the specified encoding.
+ *
* @param input the byte array to read from
- * @param output the {@code Writer} to write to
+ * @param output the {@link Writer} to write to
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
@@ -159,10 +156,11 @@
}
/**
- * Copies bytes from an {@code InputStream} to an
- * {@code OutputStream}.
- * @param input the {@code InputStream} to read from
- * @param output the {@code OutputStream} to write to
+ * Copies bytes from an {@link InputStream} to an
+ * {@link OutputStream}.
+ *
+ * @param input the {@link InputStream} to read from
+ * @param output the {@link OutputStream} to write to
* @return the number of bytes copied
* @throws IOException In case of an I/O problem
*/
@@ -177,41 +175,13 @@
return count;
}
- // ----------------------------------------------------------------
- // Reader -> Writer
- // ----------------------------------------------------------------
-
/**
- * Copies chars from a {@code Reader} to a {@code Writer}.
- * @param input the {@code Reader} to read from
- * @param output the {@code Writer} to write to
- * @return the number of characters copied
- * @throws IOException In case of an I/O problem
- */
- public static int copy(
- final Reader input,
- final Writer output)
- throws IOException {
- final char[] buffer = IOUtils.getCharArray();
- int count = 0;
- int n;
- while (EOF != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- // ----------------------------------------------------------------
- // InputStream -> Writer
- // ----------------------------------------------------------------
-
- /**
- * Copies and convert bytes from an {@code InputStream} to chars on a
- * {@code Writer}.
+ * Copies and convert bytes from an {@link InputStream} to chars on a
+ * {@link Writer}.
* The platform's default encoding is used for the byte-to-char conversion.
- * @param input the {@code InputStream} to read from
- * @param output the {@code Writer} to write to
+ *
+ * @param input the {@link InputStream} to read from
+ * @param output the {@link Writer} to write to
* @throws IOException In case of an I/O problem
* @deprecated 2.5 use {@link #copy(InputStream, Writer, String)} instead
*/
@@ -226,10 +196,11 @@
}
/**
- * Copies and convert bytes from an {@code InputStream} to chars on a
- * {@code Writer}, using the specified encoding.
- * @param input the {@code InputStream} to read from
- * @param output the {@code Writer} to write to
+ * Copies and convert bytes from an {@link InputStream} to chars on a
+ * {@link Writer}, using the specified encoding.
+ *
+ * @param input the {@link InputStream} to read from
+ * @param output the {@link Writer} to write to
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
@@ -244,17 +215,13 @@
copy(in, output);
}
-
- // ----------------------------------------------------------------
- // Reader -> OutputStream
- // ----------------------------------------------------------------
-
/**
- * Serialize chars from a {@code Reader} to bytes on an
- * {@code OutputStream}, and flush the {@code OutputStream}.
+ * Serialize chars from a {@link Reader} to bytes on an
+ * {@link OutputStream}, and flush the {@link OutputStream}.
* Uses the default platform encoding.
- * @param input the {@code Reader} to read from
- * @param output the {@code OutputStream} to write to
+ *
+ * @param input the {@link Reader} to read from
+ * @param output the {@link OutputStream} to write to
* @throws IOException In case of an I/O problem
* @deprecated 2.5 use {@link #copy(Reader, OutputStream, String)} instead
*/
@@ -272,10 +239,11 @@
}
/**
- * Serialize chars from a {@code Reader} to bytes on an
- * {@code OutputStream}, and flush the {@code OutputStream}.
- * @param input the {@code Reader} to read from
- * @param output the {@code OutputStream} to write to
+ * Serialize chars from a {@link Reader} to bytes on an
+ * {@link OutputStream}, and flush the {@link OutputStream}.
+ *
+ * @param input the {@link Reader} to read from
+ * @param output the {@link OutputStream} to write to
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
@@ -294,17 +262,36 @@
out.flush();
}
- // ----------------------------------------------------------------
- // String -> OutputStream
- // ----------------------------------------------------------------
+ /**
+ * Copies chars from a {@link Reader} to a {@link Writer}.
+ *
+ * @param input the {@link Reader} to read from
+ * @param output the {@link Writer} to write to
+ * @return the number of characters copied
+ * @throws IOException In case of an I/O problem
+ */
+ public static int copy(
+ final Reader input,
+ final Writer output)
+ throws IOException {
+ final char[] buffer = IOUtils.getScratchCharArray();
+ int count = 0;
+ int n;
+ while (EOF != (n = input.read(buffer))) {
+ output.write(buffer, 0, n);
+ count += n;
+ }
+ return count;
+ }
/**
- * Serialize chars from a {@code String} to bytes on an
- * {@code OutputStream}, and
- * flush the {@code OutputStream}.
+ * Serialize chars from a {@link String} to bytes on an
+ * {@link OutputStream}, and
+ * flush the {@link OutputStream}.
* Uses the platform default encoding.
- * @param input the {@code String} to read from
- * @param output the {@code OutputStream} to write to
+ *
+ * @param input the {@link String} to read from
+ * @param output the {@link OutputStream} to write to
* @throws IOException In case of an I/O problem
* @deprecated 2.5 use {@link #copy(String, OutputStream, String)} instead
*/
@@ -323,11 +310,12 @@
}
/**
- * Serialize chars from a {@code String} to bytes on an
- * {@code OutputStream}, and
- * flush the {@code OutputStream}.
- * @param input the {@code String} to read from
- * @param output the {@code OutputStream} to write to
+ * Serialize chars from a {@link String} to bytes on an
+ * {@link OutputStream}, and
+ * flush the {@link OutputStream}.
+ *
+ * @param input the {@link String} to read from
+ * @param output the {@link OutputStream} to write to
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
@@ -347,19 +335,21 @@
out.flush();
}
- // ----------------------------------------------------------------
- // String -> Writer
- // ----------------------------------------------------------------
-
/**
- * Copies chars from a {@code String} to a {@code Writer}.
- * @param input the {@code String} to read from
- * @param output the {@code Writer} to write to
+ * Copies chars from a {@link String} to a {@link Writer}.
+ *
+ * @param input the {@link String} to read from
+ * @param output the {@link Writer} to write to
* @throws IOException In case of an I/O problem
*/
public static void copy(final String input, final Writer output)
throws IOException {
output.write(input);
}
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public CopyUtils() { }
+
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java (.../DirectoryWalker.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/DirectoryWalker.java (.../DirectoryWalker.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -40,8 +40,8 @@
* The following sections describe:
*
* The third constructor option is to specify separate filters, one for directories and one for files. These are
- * combined internally to form the correct {@code FileFilter}, something which is very easy to get wrong when
+ * combined internally to form the correct {@link FileFilter}, something which is very easy to get wrong when
* attempted manually, particularly when trying to express constructs like 'any file in directories named docs'.
*
*
@@ -154,7 +154,7 @@
* implementation.
*
*
- * What {@code DirectoryWalker} does provide for cancellation is:
+ * What {@link DirectoryWalker} does provide for cancellation is:
*
*
*
{@link CancelException} which can be thrown in any of the lifecycle methods to stop processing.
@@ -255,16 +255,75 @@
public abstract class DirectoryWalker {
/**
+ * CancelException is thrown in DirectoryWalker to cancel the current
+ * processing.
+ */
+ public static class CancelException extends IOException {
+
+ /** Serialization id. */
+ private static final long serialVersionUID = 1347339620135041008L;
+
+ /** The file being processed when the exception was thrown. */
+ private final File file;
+ /** The file depth when the exception was thrown. */
+ private final int depth;
+
+ /**
+ * Constructs a {@link CancelException} with
+ * the file and depth when cancellation occurred.
+ *
+ * @param file the file when the operation was cancelled, may be null
+ * @param depth the depth when the operation was cancelled, may be null
+ */
+ public CancelException(final File file, final int depth) {
+ this("Operation Cancelled", file, depth);
+ }
+
+ /**
+ * Constructs a {@link CancelException} with
+ * an appropriate message and the file and depth when
+ * cancellation occurred.
+ *
+ * @param message the detail message
+ * @param file the file when the operation was cancelled
+ * @param depth the depth when the operation was cancelled
+ */
+ public CancelException(final String message, final File file, final int depth) {
+ super(message);
+ this.file = file;
+ this.depth = depth;
+ }
+
+ /**
+ * Returns the depth when the operation was cancelled.
+ *
+ * @return the depth when the operation was cancelled
+ */
+ public int getDepth() {
+ return depth;
+ }
+
+ /**
+ * Returns the file when the operation was cancelled.
+ *
+ * @return the file when the operation was cancelled
+ */
+ public File getFile() {
+ return file;
+ }
+ }
+ /**
* The file filter to use to filter files and directories.
*/
private final FileFilter filter;
+
/**
* The limit on the directory depth to walk.
*/
private final int depthLimit;
/**
- * Construct an instance with no filtering and unlimited depth.
+ * Constructs an instance with no filtering and unlimited depth.
*/
protected DirectoryWalker() {
this(null, -1);
@@ -317,72 +376,8 @@
}
/**
- * Internal method that walks the directory hierarchy in a depth-first manner.
- *
- * Users of this class do not need to call this method. This method will
- * be called automatically by another (public) method on the specific subclass.
- *
- *
- * Writers of subclasses should call this method to start the directory walk.
- * Once called, this method will emit events as it walks the hierarchy.
- * The event methods have the prefix {@code handle}.
- *
- *
- * @param startDirectory the directory to start from, not null
- * @param results the collection of result objects, may be updated
- * @throws NullPointerException if the start directory is null
- * @throws IOException if an I/O Error occurs
- */
- protected final void walk(final File startDirectory, final Collection results) throws IOException {
- Objects.requireNonNull(startDirectory, "startDirectory");
- try {
- handleStart(startDirectory, results);
- walk(startDirectory, 0, results);
- handleEnd(results);
- } catch(final CancelException cancel) {
- handleCancelled(startDirectory, results, cancel);
- }
- }
-
- /**
- * Main recursive method to examine the directory hierarchy.
- *
- * @param directory the directory to examine, not null
- * @param depth the directory level (starting directory = 0)
- * @param results the collection of result objects, may be updated
- * @throws IOException if an I/O Error occurs
- */
- private void walk(final File directory, final int depth, final Collection results) throws IOException {
- checkIfCancelled(directory, depth, results);
- if (handleDirectory(directory, depth, results)) {
- handleDirectoryStart(directory, depth, results);
- final int childDepth = depth + 1;
- if (depthLimit < 0 || childDepth <= depthLimit) {
- checkIfCancelled(directory, depth, results);
- File[] childFiles = filter == null ? directory.listFiles() : directory.listFiles(filter);
- childFiles = filterDirectoryContents(directory, depth, childFiles);
- if (childFiles == null) {
- handleRestricted(directory, childDepth, results);
- } else {
- for (final File childFile : childFiles) {
- if (childFile.isDirectory()) {
- walk(childFile, childDepth, results);
- } else {
- checkIfCancelled(childFile, childDepth, results);
- handleFile(childFile, childDepth, results);
- checkIfCancelled(childFile, childDepth, results);
- }
- }
- }
- }
- handleDirectoryEnd(directory, depth, results);
- }
- checkIfCancelled(directory, depth, results);
- }
-
- /**
* Checks whether the walk has been cancelled by calling {@link #handleIsCancelled},
- * throwing a {@code CancelException} if it has.
+ * throwing a {@link CancelException} if it has.
*
* Writers of subclasses should not normally call this method as it is called
* automatically by the walk of the tree. However, sometimes a single method,
@@ -403,48 +398,22 @@
}
/**
- * Overridable callback method invoked to determine if the entire walk
- * operation should be immediately cancelled.
+ * Overridable callback method invoked with the contents of each directory.
*
- * This method should be implemented by those subclasses that want to
- * provide a public {@code cancel()} method available from another
- * thread. The design pattern for the subclass should be as follows:
+ * This implementation returns the files unchanged
*
- * If this method returns true, then the directory walk is immediately
- * cancelled. The next callback method will be {@link #handleCancelled}.
- *
- *
- * This implementation returns false.
- *
- *
- * @param file the file or directory being processed
+ * @param directory the current directory being processed
* @param depth the current directory level (starting directory = 0)
- * @param results the collection of result objects, may be updated
- * @return true if the walk has been cancelled
+ * @param files the files (possibly filtered) in the directory, may be {@code null}
+ * @return the filtered list of files
* @throws IOException if an I/O Error occurs
+ * @since 2.0
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected boolean handleIsCancelled(
- final File file, final int depth, final Collection results) throws IOException {
- // do nothing - overridable by subclass
- return false; // not cancelled
+ protected File[] filterDirectoryContents(final File directory, final int depth, final File... files) throws
+ IOException {
+ return files;
}
/**
@@ -468,21 +437,6 @@
}
/**
- * Overridable callback method invoked at the start of processing.
- *
- * This implementation does nothing.
- *
- *
- * @param startDirectory the directory to start from
- * @param results the collection of result objects, may be updated
- * @throws IOException if an I/O Error occurs
- */
- @SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleStart(final File startDirectory, final Collection results) throws IOException {
- // do nothing - overridable by subclass
- }
-
- /**
* Overridable callback method invoked to determine if a directory should be processed.
*
* This method returns a boolean to indicate if the directory should be examined or not.
@@ -507,42 +461,54 @@
}
/**
- * Overridable callback method invoked at the start of processing each directory.
+ * Overridable callback method invoked at the end of processing each directory.
*
* This implementation does nothing.
*
*
- * @param directory the current directory being processed
+ * @param directory the directory being processed
* @param depth the current directory level (starting directory = 0)
* @param results the collection of result objects, may be updated
* @throws IOException if an I/O Error occurs
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleDirectoryStart(final File directory, final int depth, final Collection results) throws
+ protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws
IOException {
// do nothing - overridable by subclass
}
/**
- * Overridable callback method invoked with the contents of each directory.
+ * Overridable callback method invoked at the start of processing each directory.
*
- * This implementation returns the files unchanged
+ * This implementation does nothing.
*
*
* @param directory the current directory being processed
* @param depth the current directory level (starting directory = 0)
- * @param files the files (possibly filtered) in the directory, may be {@code null}
- * @return the filtered list of files
+ * @param results the collection of result objects, may be updated
* @throws IOException if an I/O Error occurs
- * @since 2.0
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected File[] filterDirectoryContents(final File directory, final int depth, final File... files) throws
+ protected void handleDirectoryStart(final File directory, final int depth, final Collection results) throws
IOException {
- return files;
+ // do nothing - overridable by subclass
}
/**
+ * Overridable callback method invoked at the end of processing.
+ *
+ * This implementation does nothing.
+ *
+ *
+ * @param results the collection of result objects, may be updated
+ * @throws IOException if an I/O Error occurs
+ */
+ @SuppressWarnings("unused") // Possibly thrown from subclasses.
+ protected void handleEnd(final Collection results) throws IOException {
+ // do nothing - overridable by subclass
+ }
+
+ /**
* Overridable callback method invoked for each (non-directory) file.
*
* This implementation does nothing.
@@ -559,109 +525,143 @@
}
/**
- * Overridable callback method invoked for each restricted directory.
+ * Overridable callback method invoked to determine if the entire walk
+ * operation should be immediately cancelled.
*
- * This implementation does nothing.
+ * This method should be implemented by those subclasses that want to
+ * provide a public {@code cancel()} method available from another
+ * thread. The design pattern for the subclass should be as follows:
*
+ * If this method returns true, then the directory walk is immediately
+ * cancelled. The next callback method will be {@link #handleCancelled}.
+ *
+ *
+ * This implementation returns false.
+ *
+ *
+ * @param file the file or directory being processed
* @param depth the current directory level (starting directory = 0)
* @param results the collection of result objects, may be updated
+ * @return true if the walk has been cancelled
* @throws IOException if an I/O Error occurs
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleRestricted(final File directory, final int depth, final Collection results) throws
- IOException {
+ protected boolean handleIsCancelled(
+ final File file, final int depth, final Collection results) throws IOException {
// do nothing - overridable by subclass
+ return false; // not cancelled
}
/**
- * Overridable callback method invoked at the end of processing each directory.
+ * Overridable callback method invoked for each restricted directory.
*
* This implementation does nothing.
*
*
- * @param directory the directory being processed
+ * @param directory the restricted directory
* @param depth the current directory level (starting directory = 0)
* @param results the collection of result objects, may be updated
* @throws IOException if an I/O Error occurs
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleDirectoryEnd(final File directory, final int depth, final Collection results) throws
+ protected void handleRestricted(final File directory, final int depth, final Collection results) throws
IOException {
// do nothing - overridable by subclass
}
/**
- * Overridable callback method invoked at the end of processing.
+ * Overridable callback method invoked at the start of processing.
*
* This implementation does nothing.
*
*
+ * @param startDirectory the directory to start from
* @param results the collection of result objects, may be updated
* @throws IOException if an I/O Error occurs
*/
@SuppressWarnings("unused") // Possibly thrown from subclasses.
- protected void handleEnd(final Collection results) throws IOException {
+ protected void handleStart(final File startDirectory, final Collection results) throws IOException {
// do nothing - overridable by subclass
}
/**
- * CancelException is thrown in DirectoryWalker to cancel the current
- * processing.
+ * Internal method that walks the directory hierarchy in a depth-first manner.
+ *
+ * Users of this class do not need to call this method. This method will
+ * be called automatically by another (public) method on the specific subclass.
+ *
+ *
+ * Writers of subclasses should call this method to start the directory walk.
+ * Once called, this method will emit events as it walks the hierarchy.
+ * The event methods have the prefix {@code handle}.
+ *
+ *
+ * @param startDirectory the directory to start from, not null
+ * @param results the collection of result objects, may be updated
+ * @throws NullPointerException if the start directory is null
+ * @throws IOException if an I/O Error occurs
*/
- public static class CancelException extends IOException {
-
- /** Serialization id. */
- private static final long serialVersionUID = 1347339620135041008L;
-
- /** The file being processed when the exception was thrown. */
- private final File file;
- /** The file depth when the exception was thrown. */
- private final int depth;
-
- /**
- * Constructs a {@code CancelException} with
- * the file and depth when cancellation occurred.
- *
- * @param file the file when the operation was cancelled, may be null
- * @param depth the depth when the operation was cancelled, may be null
- */
- public CancelException(final File file, final int depth) {
- this("Operation Cancelled", file, depth);
+ protected final void walk(final File startDirectory, final Collection results) throws IOException {
+ Objects.requireNonNull(startDirectory, "startDirectory");
+ try {
+ handleStart(startDirectory, results);
+ walk(startDirectory, 0, results);
+ handleEnd(results);
+ } catch (final CancelException cancel) {
+ handleCancelled(startDirectory, results, cancel);
}
+ }
- /**
- * Constructs a {@code CancelException} with
- * an appropriate message and the file and depth when
- * cancellation occurred.
- *
- * @param message the detail message
- * @param file the file when the operation was cancelled
- * @param depth the depth when the operation was cancelled
- */
- public CancelException(final String message, final File file, final int depth) {
- super(message);
- this.file = file;
- this.depth = depth;
+ /**
+ * Main recursive method to examine the directory hierarchy.
+ *
+ * @param directory the directory to examine, not null
+ * @param depth the directory level (starting directory = 0)
+ * @param results the collection of result objects, may be updated
+ * @throws IOException if an I/O Error occurs
+ */
+ private void walk(final File directory, final int depth, final Collection results) throws IOException {
+ checkIfCancelled(directory, depth, results);
+ if (handleDirectory(directory, depth, results)) {
+ handleDirectoryStart(directory, depth, results);
+ final int childDepth = depth + 1;
+ if (depthLimit < 0 || childDepth <= depthLimit) {
+ checkIfCancelled(directory, depth, results);
+ File[] childFiles = filter == null ? directory.listFiles() : directory.listFiles(filter);
+ childFiles = filterDirectoryContents(directory, depth, childFiles);
+ if (childFiles == null) {
+ handleRestricted(directory, childDepth, results);
+ } else {
+ for (final File childFile : childFiles) {
+ if (childFile.isDirectory()) {
+ walk(childFile, childDepth, results);
+ } else {
+ checkIfCancelled(childFile, childDepth, results);
+ handleFile(childFile, childDepth, results);
+ checkIfCancelled(childFile, childDepth, results);
+ }
+ }
+ }
+ }
+ handleDirectoryEnd(directory, depth, results);
}
-
- /**
- * Returns the file when the operation was cancelled.
- *
- * @return the file when the operation was cancelled
- */
- public File getFile() {
- return file;
- }
-
- /**
- * Returns the depth when the operation was cancelled.
- *
- * @return the depth when the operation was cancelled
- */
- public int getDepth() {
- return depth;
- }
+ checkIfCancelled(directory, depth, results);
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java (.../EndianUtils.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/EndianUtils.java (.../EndianUtils.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,191 +24,111 @@
import java.io.OutputStream;
/**
- * Utility code for dealing with different endian systems.
+ * Helps with different endian systems.
*
* Different computer architectures adopt different conventions for
* byte ordering. In so-called "Little Endian" architectures (eg Intel),
* the low-order byte is stored in memory at the lowest address, and
* subsequent bytes at higher addresses. For "Big Endian" architectures
* (eg Motorola), the situation is reversed.
* This class helps you solve this incompatibility.
+ *
*
* @see org.apache.commons.io.input.SwappedDataInputStream
*/
public class EndianUtils {
/**
- * Instances should NOT be constructed in standard programming.
+ * Reads the next byte from the input stream.
+ * @param input the stream
+ * @return the byte
+ * @throws IOException if the end of file is reached
*/
- public EndianUtils() {
+ private static int read(final InputStream input) throws IOException {
+ final int value = input.read();
+ if (EOF == value) {
+ throw new EOFException("Unexpected EOF reached");
+ }
+ return value;
}
- // ========================================== Swapping routines
-
/**
- * Converts a "short" value between endian systems.
- * @param value value to convert
- * @return the converted value
- */
- public static short swapShort(final short value) {
- return (short) ( ( ( ( value >> 0 ) & 0xff ) << 8 ) +
- ( ( ( value >> 8 ) & 0xff ) << 0 ) );
- }
-
- /**
- * Converts a "int" value between endian systems.
- * @param value value to convert
- * @return the converted value
- */
- public static int swapInteger(final int value) {
- return
- ( ( ( value >> 0 ) & 0xff ) << 24 ) +
- ( ( ( value >> 8 ) & 0xff ) << 16 ) +
- ( ( ( value >> 16 ) & 0xff ) << 8 ) +
- ( ( ( value >> 24 ) & 0xff ) << 0 );
- }
-
- /**
- * Converts a "long" value between endian systems.
- * @param value value to convert
- * @return the converted value
- */
- public static long swapLong(final long value) {
- return
- ( ( ( value >> 0 ) & 0xff ) << 56 ) +
- ( ( ( value >> 8 ) & 0xff ) << 48 ) +
- ( ( ( value >> 16 ) & 0xff ) << 40 ) +
- ( ( ( value >> 24 ) & 0xff ) << 32 ) +
- ( ( ( value >> 32 ) & 0xff ) << 24 ) +
- ( ( ( value >> 40 ) & 0xff ) << 16 ) +
- ( ( ( value >> 48 ) & 0xff ) << 8 ) +
- ( ( ( value >> 56 ) & 0xff ) << 0 );
- }
-
- /**
- * Converts a "float" value between endian systems.
- * @param value value to convert
- * @return the converted value
- */
- public static float swapFloat(final float value) {
- return Float.intBitsToFloat( swapInteger( Float.floatToIntBits( value ) ) );
- }
-
- /**
- * Converts a "double" value between endian systems.
- * @param value value to convert
- * @return the converted value
- */
- public static double swapDouble(final double value) {
- return Double.longBitsToDouble( swapLong( Double.doubleToLongBits( value ) ) );
- }
-
- // ========================================== Swapping read/write routines
-
- /**
- * Writes a "short" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
+ * Reads a "double" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
+ * @param data source byte array
* @param offset starting offset in the byte array
- * @param value value to write
+ * @return the value read
*/
- public static void writeSwappedShort(final byte[] data, final int offset, final short value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
+ public static double readSwappedDouble(final byte[] data, final int offset) {
+ return Double.longBitsToDouble(readSwappedLong(data, offset));
}
/**
- * Reads a "short" value from a byte array at a given offset. The value is
+ * Reads a "double" value from an InputStream. The value is
* converted to the opposed endian system while reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static short readSwappedShort(final byte[] data, final int offset) {
- return (short)( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
+ public static double readSwappedDouble(final InputStream input) throws IOException {
+ return Double.longBitsToDouble(readSwappedLong(input));
}
/**
- * Reads an unsigned short (16-bit) value from a byte array at a given
- * offset. The value is converted to the opposed endian system while
- * reading.
+ * Reads a "float" value from a byte array at a given offset. The value is
+ * converted to the opposed endian system while reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
- public static int readSwappedUnsignedShort(final byte[] data, final int offset) {
- return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) );
+ public static float readSwappedFloat(final byte[] data, final int offset) {
+ return Float.intBitsToFloat(readSwappedInteger(data, offset));
}
/**
- * Writes a "int" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a "float" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedInteger(final byte[] data, final int offset, final int value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
- data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
- data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
+ public static float readSwappedFloat(final InputStream input) throws IOException {
+ return Float.intBitsToFloat(readSwappedInteger(input));
}
/**
- * Reads a "int" value from a byte array at a given offset. The value is
+ * Reads an "int" value from a byte array at a given offset. The value is
* converted to the opposed endian system while reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
public static int readSwappedInteger(final byte[] data, final int offset) {
- return ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) +
- ( ( data[ offset + 2 ] & 0xff ) << 16 ) +
- ( ( data[ offset + 3 ] & 0xff ) << 24 ) );
+ return ((data[offset + 0] & 0xff) << 0) +
+ ((data[offset + 1] & 0xff) << 8) +
+ ((data[offset + 2] & 0xff) << 16) +
+ ((data[offset + 3] & 0xff) << 24);
}
/**
- * Reads an unsigned integer (32-bit) value from a byte array at a given
- * offset. The value is converted to the opposed endian system while
- * reading.
- * @param data source byte array
- * @param offset starting offset in the byte array
- * @return the value read
+ * Reads an "int" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static long readSwappedUnsignedInteger(final byte[] data, final int offset) {
- final long low = ( ( ( data[ offset + 0 ] & 0xff ) << 0 ) +
- ( ( data[ offset + 1 ] & 0xff ) << 8 ) +
- ( ( data[ offset + 2 ] & 0xff ) << 16 ) );
-
- final long high = data[ offset + 3 ] & 0xff;
-
- return (high << 24) + (0xffffffffL & low);
+ public static int readSwappedInteger(final InputStream input) throws IOException {
+ final int value1 = read(input);
+ final int value2 = read(input);
+ final int value3 = read(input);
+ final int value4 = read(input);
+ return ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16) + ((value4 & 0xff) << 24);
}
/**
- * Writes a "long" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
- */
- public static void writeSwappedLong(final byte[] data, final int offset, final long value) {
- data[ offset + 0 ] = (byte)( ( value >> 0 ) & 0xff );
- data[ offset + 1 ] = (byte)( ( value >> 8 ) & 0xff );
- data[ offset + 2 ] = (byte)( ( value >> 16 ) & 0xff );
- data[ offset + 3 ] = (byte)( ( value >> 24 ) & 0xff );
- data[ offset + 4 ] = (byte)( ( value >> 32 ) & 0xff );
- data[ offset + 5 ] = (byte)( ( value >> 40 ) & 0xff );
- data[ offset + 6 ] = (byte)( ( value >> 48 ) & 0xff );
- data[ offset + 7 ] = (byte)( ( value >> 56 ) & 0xff );
- }
-
- /**
* Reads a "long" value from a byte array at a given offset. The value is
* converted to the opposed endian system while reading.
* @param data source byte array
@@ -222,74 +142,89 @@
}
/**
- * Writes a "float" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a "long" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedFloat(final byte[] data, final int offset, final float value) {
- writeSwappedInteger( data, offset, Float.floatToIntBits( value ) );
+ public static long readSwappedLong(final InputStream input) throws IOException {
+ final byte[] bytes = new byte[8];
+ for (int i = 0; i < 8; i++) {
+ bytes[i] = (byte) read(input);
+ }
+ return readSwappedLong(bytes, 0);
}
/**
- * Reads a "float" value from a byte array at a given offset. The value is
+ * Reads a "short" value from a byte array at a given offset. The value is
* converted to the opposed endian system while reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
- public static float readSwappedFloat(final byte[] data, final int offset) {
- return Float.intBitsToFloat( readSwappedInteger( data, offset ) );
+ public static short readSwappedShort(final byte[] data, final int offset) {
+ return (short) (((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8));
}
/**
- * Writes a "double" value to a byte array at a given offset. The value is
- * converted to the opposed endian system while writing.
- * @param data target byte array
- * @param offset starting offset in the byte array
- * @param value value to write
+ * Reads a "short" value from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
+ * @throws IOException in case of an I/O problem
*/
- public static void writeSwappedDouble(final byte[] data, final int offset, final double value) {
- writeSwappedLong( data, offset, Double.doubleToLongBits( value ) );
+ public static short readSwappedShort(final InputStream input) throws IOException {
+ return (short) (((read(input) & 0xff) << 0) + ((read(input) & 0xff) << 8));
}
/**
- * Reads a "double" value from a byte array at a given offset. The value is
- * converted to the opposed endian system while reading.
+ * Reads an unsigned integer (32-bit) value from a byte array at a given
+ * offset. The value is converted to the opposed endian system while
+ * reading.
* @param data source byte array
* @param offset starting offset in the byte array
* @return the value read
*/
- public static double readSwappedDouble(final byte[] data, final int offset) {
- return Double.longBitsToDouble( readSwappedLong( data, offset ) );
+ public static long readSwappedUnsignedInteger(final byte[] data, final int offset) {
+ final long low = ((data[offset + 0] & 0xff) << 0) +
+ ((data[offset + 1] & 0xff) << 8) +
+ ((data[offset + 2] & 0xff) << 16);
+ final long high = data[offset + 3] & 0xff;
+ return (high << 24) + (0xffffffffL & low);
}
/**
- * Writes a "short" value to an OutputStream. The value is
- * converted to the opposed endian system while writing.
- * @param output target OutputStream
- * @param value value to write
+ * Reads an unsigned integer (32-bit) from an InputStream. The value is
+ * converted to the opposed endian system while reading.
+ * @param input source InputStream
+ * @return the value just read
* @throws IOException in case of an I/O problem
*/
- public static void writeSwappedShort(final OutputStream output, final short value) throws IOException {
- output.write((byte) ((value >> 0) & 0xff));
- output.write((byte) ((value >> 8) & 0xff));
+ public static long readSwappedUnsignedInteger(final InputStream input) throws IOException {
+ final int value1 = read(input);
+ final int value2 = read(input);
+ final int value3 = read(input);
+ final int value4 = read(input);
+ final long low = ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16);
+ final long high = value4 & 0xff;
+ return (high << 24) + (0xffffffffL & low);
}
/**
- * Reads a "short" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Reads an unsigned short (16-bit) value from a byte array at a given
+ * offset. The value is converted to the opposed endian system while
+ * reading.
+ * @param data source byte array
+ * @param offset starting offset in the byte array
+ * @return the value read
*/
- public static short readSwappedShort(final InputStream input) throws IOException {
- return (short) (((read(input) & 0xff) << 0) + ((read(input) & 0xff) << 8));
+ public static int readSwappedUnsignedShort(final byte[] data, final int offset) {
+ return ((data[offset + 0] & 0xff) << 0) + ((data[offset + 1] & 0xff) << 8);
}
/**
- * Reads a unsigned short (16-bit) from an InputStream. The value is
+ * Reads an unsigned short (16-bit) from an InputStream. The value is
* converted to the opposed endian system while reading.
* @param input source InputStream
* @return the value just read
@@ -299,90 +234,98 @@
final int value1 = read(input);
final int value2 = read(input);
- return (((value1 & 0xff) << 0) + ((value2 & 0xff) << 8));
+ return ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8);
}
/**
- * Writes a "int" value to an OutputStream. The value is converted to the opposed endian system while writing.
- *
- * @param output target OutputStream
- * @param value value to write
- * @throws IOException in case of an I/O problem
+ * Converts a "double" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
*/
- public static void writeSwappedInteger(final OutputStream output, final int value) throws IOException {
- output.write((byte) ((value >> 0) & 0xff));
- output.write((byte) ((value >> 8) & 0xff));
- output.write((byte) ((value >> 16) & 0xff));
- output.write((byte) ((value >> 24) & 0xff));
+ public static double swapDouble(final double value) {
+ return Double.longBitsToDouble(swapLong(Double.doubleToLongBits(value)));
}
/**
- * Reads a "int" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Converts a "float" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
*/
- public static int readSwappedInteger(final InputStream input) throws IOException {
- final int value1 = read(input);
- final int value2 = read(input);
- final int value3 = read(input);
- final int value4 = read(input);
+ public static float swapFloat(final float value) {
+ return Float.intBitsToFloat(swapInteger(Float.floatToIntBits(value)));
+ }
- return ((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16) + ((value4 & 0xff) << 24);
+ /**
+ * Converts an "int" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
+ */
+ public static int swapInteger(final int value) {
+ return
+ ((value >> 0 & 0xff) << 24) +
+ ((value >> 8 & 0xff) << 16) +
+ ((value >> 16 & 0xff) << 8) +
+ ((value >> 24 & 0xff) << 0);
}
/**
- * Reads a unsigned integer (32-bit) from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Converts a "long" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
*/
- public static long readSwappedUnsignedInteger(final InputStream input) throws IOException {
- final int value1 = read(input);
- final int value2 = read(input);
- final int value3 = read(input);
- final int value4 = read(input);
+ public static long swapLong(final long value) {
+ return
+ ((value >> 0 & 0xff) << 56) +
+ ((value >> 8 & 0xff) << 48) +
+ ((value >> 16 & 0xff) << 40) +
+ ((value >> 24 & 0xff) << 32) +
+ ((value >> 32 & 0xff) << 24) +
+ ((value >> 40 & 0xff) << 16) +
+ ((value >> 48 & 0xff) << 8) +
+ ((value >> 56 & 0xff) << 0);
+ }
- final long low = (((value1 & 0xff) << 0) + ((value2 & 0xff) << 8) + ((value3 & 0xff) << 16));
+ /**
+ * Converts a "short" value between endian systems.
+ * @param value value to convert
+ * @return the converted value
+ */
+ public static short swapShort(final short value) {
+ return (short) (((value >> 0 & 0xff) << 8) +
+ ((value >> 8 & 0xff) << 0));
+ }
- final long high = value4 & 0xff;
-
- return (high << 24) + (0xffffffffL & low);
+ /**
+ * Writes a "double" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
+ */
+ public static void writeSwappedDouble(final byte[] data, final int offset, final double value) {
+ writeSwappedLong(data, offset, Double.doubleToLongBits(value));
}
/**
- * Writes a "long" value to an OutputStream. The value is
+ * Writes a "double" value to an OutputStream. The value is
* converted to the opposed endian system while writing.
* @param output target OutputStream
* @param value value to write
* @throws IOException in case of an I/O problem
*/
- public static void writeSwappedLong(final OutputStream output, final long value) throws IOException {
- output.write((byte) ((value >> 0) & 0xff));
- output.write((byte) ((value >> 8) & 0xff));
- output.write((byte) ((value >> 16) & 0xff));
- output.write((byte) ((value >> 24) & 0xff));
- output.write((byte) ((value >> 32) & 0xff));
- output.write((byte) ((value >> 40) & 0xff));
- output.write((byte) ((value >> 48) & 0xff));
- output.write((byte) ((value >> 56) & 0xff));
+ public static void writeSwappedDouble(final OutputStream output, final double value) throws IOException {
+ writeSwappedLong(output, Double.doubleToLongBits(value));
}
/**
- * Reads a "long" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Writes a "float" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
*/
- public static long readSwappedLong(final InputStream input) throws IOException {
- final byte[] bytes = new byte[8];
- for (int i = 0; i < 8; i++) {
- bytes[i] = (byte) read(input);
- }
- return readSwappedLong(bytes, 0);
+ public static void writeSwappedFloat(final byte[] data, final int offset, final float value) {
+ writeSwappedInteger(data, offset, Float.floatToIntBits(value));
}
/**
@@ -397,51 +340,96 @@
}
/**
- * Reads a "float" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
+ * Writes an "int" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
+ */
+ public static void writeSwappedInteger(final byte[] data, final int offset, final int value) {
+ data[offset + 0] = (byte) (value >> 0 & 0xff);
+ data[offset + 1] = (byte) (value >> 8 & 0xff);
+ data[offset + 2] = (byte) (value >> 16 & 0xff);
+ data[offset + 3] = (byte) (value >> 24 & 0xff);
+ }
+
+ /**
+ * Writes an "int" value to an OutputStream. The value is converted to the opposed endian system while writing.
+ *
+ * @param output target OutputStream
+ * @param value value to write
* @throws IOException in case of an I/O problem
*/
- public static float readSwappedFloat(final InputStream input) throws IOException {
- return Float.intBitsToFloat(readSwappedInteger(input));
+ public static void writeSwappedInteger(final OutputStream output, final int value) throws IOException {
+ output.write((byte) (value >> 0 & 0xff));
+ output.write((byte) (value >> 8 & 0xff));
+ output.write((byte) (value >> 16 & 0xff));
+ output.write((byte) (value >> 24 & 0xff));
}
/**
- * Writes a "double" value to an OutputStream. The value is
+ * Writes a "long" value to a byte array at a given offset. The value is
* converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
+ */
+ public static void writeSwappedLong(final byte[] data, final int offset, final long value) {
+ data[offset + 0] = (byte) (value >> 0 & 0xff);
+ data[offset + 1] = (byte) (value >> 8 & 0xff);
+ data[offset + 2] = (byte) (value >> 16 & 0xff);
+ data[offset + 3] = (byte) (value >> 24 & 0xff);
+ data[offset + 4] = (byte) (value >> 32 & 0xff);
+ data[offset + 5] = (byte) (value >> 40 & 0xff);
+ data[offset + 6] = (byte) (value >> 48 & 0xff);
+ data[offset + 7] = (byte) (value >> 56 & 0xff);
+ }
+
+ /**
+ * Writes a "long" value to an OutputStream. The value is
+ * converted to the opposed endian system while writing.
* @param output target OutputStream
* @param value value to write
* @throws IOException in case of an I/O problem
*/
- public static void writeSwappedDouble(final OutputStream output, final double value) throws IOException {
- writeSwappedLong(output, Double.doubleToLongBits(value));
+ public static void writeSwappedLong(final OutputStream output, final long value) throws IOException {
+ output.write((byte) (value >> 0 & 0xff));
+ output.write((byte) (value >> 8 & 0xff));
+ output.write((byte) (value >> 16 & 0xff));
+ output.write((byte) (value >> 24 & 0xff));
+ output.write((byte) (value >> 32 & 0xff));
+ output.write((byte) (value >> 40 & 0xff));
+ output.write((byte) (value >> 48 & 0xff));
+ output.write((byte) (value >> 56 & 0xff));
}
/**
- * Reads a "double" value from an InputStream. The value is
- * converted to the opposed endian system while reading.
- * @param input source InputStream
- * @return the value just read
- * @throws IOException in case of an I/O problem
+ * Writes a "short" value to a byte array at a given offset. The value is
+ * converted to the opposed endian system while writing.
+ * @param data target byte array
+ * @param offset starting offset in the byte array
+ * @param value value to write
*/
- public static double readSwappedDouble(final InputStream input) throws IOException {
- return Double.longBitsToDouble(readSwappedLong(input));
+ public static void writeSwappedShort(final byte[] data, final int offset, final short value) {
+ data[offset + 0] = (byte) (value >> 0 & 0xff);
+ data[offset + 1] = (byte) (value >> 8 & 0xff);
}
/**
- * Reads the next byte from the input stream.
- * @param input the stream
- * @return the byte
- * @throws IOException if the end of file is reached
+ * Writes a "short" value to an OutputStream. The value is
+ * converted to the opposed endian system while writing.
+ * @param output target OutputStream
+ * @param value value to write
+ * @throws IOException in case of an I/O problem
*/
- private static int read(final InputStream input) throws IOException {
- final int value = input.read();
+ public static void writeSwappedShort(final OutputStream output, final short value) throws IOException {
+ output.write((byte) (value >> 0 & 0xff));
+ output.write((byte) (value >> 8 & 0xff));
+ }
- if (EOF == value) {
- throw new EOFException("Unexpected EOF reached");
- }
-
- return value;
+ /**
+ * Instances should NOT be constructed in standard programming.
+ */
+ public EndianUtils() {
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java (.../FileCleaner.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaner.java (.../FileCleaner.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -36,12 +36,65 @@
*/
@Deprecated
public class FileCleaner {
+
/**
* The instance to use for the deprecated, static methods.
*/
- static final FileCleaningTracker theInstance = new FileCleaningTracker();
+ private static final FileCleaningTracker INSTANCE = new FileCleaningTracker();
/**
+ * Call this method to cause the file cleaner thread to terminate when
+ * there are no more objects being tracked for deletion.
+ *
+ * In a simple environment, you don't need this method as the file cleaner
+ * thread will simply exit when the JVM exits. In a more complex environment,
+ * with multiple class loaders (such as an application server), you should be
+ * aware that the file cleaner thread will continue running even if the class
+ * loader it was started from terminates. This can constitute a memory leak.
+ *
+ * For example, suppose that you have developed a web application, which
+ * contains the commons-io jar file in your WEB-INF/lib directory. In other
+ * words, the FileCleaner class is loaded through the class loader of your
+ * web application. If the web application is terminated, but the servlet
+ * container is still running, then the file cleaner thread will still exist,
+ * posing a memory leak.
+ *
+ * This method allows the thread to be terminated. Simply call this method
+ * in the resource cleanup code, such as
+ * {@code javax.servlet.ServletContextListener.contextDestroyed(javax.servlet.ServletContextEvent)}.
+ * One called, no new objects can be tracked by the file cleaner.
+ * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}.
+ */
+ @Deprecated
+ public static synchronized void exitWhenFinished() {
+ INSTANCE.exitWhenFinished();
+ }
+
+ /**
+ * Gets the singleton instance, which is used by the deprecated, static methods.
+ * This is mainly useful for code, which wants to support the new
+ * {@link FileCleaningTracker} class while maintain compatibility with the
+ * deprecated {@link FileCleaner}.
+ *
+ * @return the singleton instance
+ */
+ public static FileCleaningTracker getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Gets the number of files currently being tracked, and therefore
+ * awaiting deletion.
+ *
+ * @return the number of files being tracked
+ * @deprecated Use {@link FileCleaningTracker#getTrackCount()}.
+ */
+ @Deprecated
+ public static int getTrackCount() {
+ return INSTANCE.getTrackCount();
+ }
+
+ /**
* Track 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.
@@ -53,7 +106,7 @@
*/
@Deprecated
public static void track(final File file, final Object marker) {
- theInstance.track(file, marker);
+ INSTANCE.track(file, marker);
}
/**
@@ -69,7 +122,7 @@
*/
@Deprecated
public static void track(final File file, final Object marker, final FileDeleteStrategy deleteStrategy) {
- theInstance.track(file, marker, deleteStrategy);
+ INSTANCE.track(file, marker, deleteStrategy);
}
/**
@@ -84,7 +137,7 @@
*/
@Deprecated
public static void track(final String path, final Object marker) {
- theInstance.track(path, marker);
+ INSTANCE.track(path, marker);
}
/**
@@ -100,58 +153,6 @@
*/
@Deprecated
public static void track(final String path, final Object marker, final FileDeleteStrategy deleteStrategy) {
- theInstance.track(path, marker, deleteStrategy);
+ INSTANCE.track(path, marker, deleteStrategy);
}
-
- /**
- * Retrieve the number of files currently being tracked, and therefore
- * awaiting deletion.
- *
- * @return the number of files being tracked
- * @deprecated Use {@link FileCleaningTracker#getTrackCount()}.
- */
- @Deprecated
- public static int getTrackCount() {
- return theInstance.getTrackCount();
- }
-
- /**
- * Call this method to cause the file cleaner thread to terminate when
- * there are no more objects being tracked for deletion.
- *
- * In a simple environment, you don't need this method as the file cleaner
- * thread will simply exit when the JVM exits. In a more complex environment,
- * with multiple class loaders (such as an application server), you should be
- * aware that the file cleaner thread will continue running even if the class
- * loader it was started from terminates. This can constitute a memory leak.
- *
- * For example, suppose that you have developed a web application, which
- * contains the commons-io jar file in your WEB-INF/lib directory. In other
- * words, the FileCleaner class is loaded through the class loader of your
- * web application. If the web application is terminated, but the servlet
- * container is still running, then the file cleaner thread will still exist,
- * posing a memory leak.
- *
- * This method allows the thread to be terminated. Simply call this method
- * in the resource cleanup code, such as
- * {@code javax.servlet.ServletContextListener.contextDestroyed(javax.servlet.ServletContextEvent)}.
- * One called, no new objects can be tracked by the file cleaner.
- * @deprecated Use {@link FileCleaningTracker#exitWhenFinished()}.
- */
- @Deprecated
- public static synchronized void exitWhenFinished() {
- theInstance.exitWhenFinished();
- }
-
- /**
- * Returns the singleton instance, which is used by the deprecated, static methods.
- * This is mainly useful for code, which wants to support the new
- * {@link FileCleaningTracker} class while maintain compatibility with the
- * deprecated {@link FileCleaner}.
- *
- * @return the singleton instance
- */
- public static FileCleaningTracker getInstance() {
- return theInstance;
- }
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java (.../FileCleaningTracker.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/FileCleaningTracker.java (.../FileCleaningTracker.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -19,6 +19,7 @@
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;
@@ -33,96 +34,129 @@
* This utility creates a background thread to handle file deletion.
* Each file to be deleted is registered with a handler object.
* When the handler object is garbage collected, the file is deleted.
+ *
*
* In an environment with multiple class loaders (a servlet container, for
* example), you should consider stopping the background thread if it is no
* longer needed. This is done by invoking the method
* {@link #exitWhenFinished}, typically in
* {@code javax.servlet.ServletContextListener.contextDestroyed(javax.servlet.ServletContextEvent)} or similar.
- *
+ *
*/
public class FileCleaningTracker {
// Note: fields are package protected to allow use by test cases
/**
- * Queue of {@code Tracker} instances being watched.
+ * The reaper thread.
*/
+ private final class Reaper extends Thread {
+ /** Constructs a new Reaper */
+ Reaper() {
+ super("File Reaper");
+ setPriority(Thread.MAX_PRIORITY);
+ setDaemon(true);
+ }
+
+ /**
+ * Runs the reaper thread that will delete files as their associated
+ * marker objects are reclaimed by the garbage collector.
+ */
+ @Override
+ public void run() {
+ // thread exits when exitWhenFinished is true and there are no more tracked objects
+ while (!exitWhenFinished || !trackers.isEmpty()) {
+ try {
+ // Wait for a tracker to remove.
+ final Tracker tracker = (Tracker) q.remove(); // cannot return null
+ trackers.remove(tracker);
+ if (!tracker.delete()) {
+ deleteFailures.add(tracker.getPath());
+ }
+ tracker.clear();
+ } catch (final InterruptedException e) {
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * Inner class which acts as the reference for a file pending deletion.
+ */
+ private static final class Tracker extends PhantomReference
*
- * @param source the file or directory to be moved
- * @param destination the destination file or directory
- * @throws FileNotFoundException if {@code source} file does not exist
+ * @param source the file or directory to be moved.
+ * @param destination the destination file or directory.
+ * @throws NullPointerException if any of the given {@link File}s are {@code null}.
+ * @throws FileNotFoundException if the source file does not exist.
*/
private static void validateMoveParameters(final File source, final File destination) throws FileNotFoundException {
Objects.requireNonNull(source, "source");
@@ -3126,9 +3138,9 @@
}
/**
- * Waits for NFS to propagate a file creation, imposing a timeout.
+ * Waits for the file system to propagate a file creation, with a timeout.
*
- * This method repeatedly tests {@link File#exists()} until it returns
+ * This method repeatedly tests {@link Files#exists(Path, LinkOption...)} until it returns
* true up to the maximum time specified in seconds.
*
*
@@ -3139,28 +3151,7 @@
*/
public static boolean waitFor(final File file, final int seconds) {
Objects.requireNonNull(file, "file");
- final long finishAtMillis = System.currentTimeMillis() + (seconds * 1000L);
- boolean wasInterrupted = false;
- try {
- while (!file.exists()) {
- final long remainingMillis = finishAtMillis - System.currentTimeMillis();
- if (remainingMillis < 0){
- return false;
- }
- try {
- Thread.sleep(Math.min(100, remainingMillis));
- } catch (final InterruptedException ignore) {
- wasInterrupted = true;
- } catch (final Exception ex) {
- break;
- }
- }
- } finally {
- if (wasInterrupted) {
- Thread.currentThread().interrupt();
- }
- }
- return true;
+ return PathUtils.waitFor(file.toPath(), Duration.ofSeconds(seconds), PathUtils.EMPTY_LINK_OPTION_ARRAY);
}
/**
@@ -3217,13 +3208,10 @@
* @throws IOException in case of an I/O error
* @since 2.3
*/
- public static void write(final File file, final CharSequence data, final Charset charset, final boolean append)
- throws IOException {
+ public static void write(final File file, final CharSequence data, final Charset charset, final boolean append) throws IOException {
writeStringToFile(file, Objects.toString(data, null), charset, append);
}
- // Private method, must be invoked will a directory parameter
-
/**
* Writes a CharSequence to a file creating the file if it does not exist.
*
@@ -3251,11 +3239,12 @@
* .UnsupportedEncodingException} in version 2.2 if the encoding is not supported by the VM
* @since 2.1
*/
- public static void write(final File file, final CharSequence data, final String charsetName, final boolean append)
- throws IOException {
+ public static void write(final File file, final CharSequence data, final String charsetName, final boolean append) throws IOException {
write(file, data, Charsets.toCharset(charsetName), append);
}
+ // Must be called with a directory
+
/**
* Writes a byte array to a file creating the file if it does not exist.
*
@@ -3272,8 +3261,6 @@
writeByteArrayToFile(file, data, false);
}
- // Must be called with a directory
-
/**
* Writes a byte array to a file creating the file if it does not exist.
*
@@ -3284,8 +3271,7 @@
* @throws IOException in case of an I/O error
* @since 2.1
*/
- public static void writeByteArrayToFile(final File file, final byte[] data, final boolean append)
- throws IOException {
+ public static void writeByteArrayToFile(final File file, final byte[] data, final boolean append) throws IOException {
writeByteArrayToFile(file, data, 0, data.length, append);
}
@@ -3301,8 +3287,7 @@
* @throws IOException in case of an I/O error
* @since 2.5
*/
- public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len)
- throws IOException {
+ public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len) throws IOException {
writeByteArrayToFile(file, data, off, len, false);
}
@@ -3320,16 +3305,15 @@
* @throws IOException in case of an I/O error
* @since 2.5
*/
- public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len,
- final boolean append) throws IOException {
- try (OutputStream out = openOutputStream(file, append)) {
+ public static void writeByteArrayToFile(final File file, final byte[] data, final int off, final int len, final boolean append) throws IOException {
+ try (OutputStream out = newOutputStream(file, append)) {
out.write(data, off, len);
}
}
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The default VM encoding and the default line ending will be used.
*
* @param file the file to write to
@@ -3343,7 +3327,7 @@
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The default VM encoding and the default line ending will be used.
*
* @param file the file to write to
@@ -3359,7 +3343,7 @@
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The default VM encoding and the specified line ending will be used.
*
* @param file the file to write to
@@ -3368,15 +3352,13 @@
* @throws IOException in case of an I/O error
* @since 1.3
*/
- public static void writeLines(final File file, final Collection> lines, final String lineEnding)
- throws IOException {
+ public static void writeLines(final File file, final Collection> lines, final String lineEnding) throws IOException {
writeLines(file, null, lines, lineEnding, false);
}
-
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The default VM encoding and the specified line ending will be used.
*
* @param file the file to write to
@@ -3387,14 +3369,13 @@
* @throws IOException in case of an I/O error
* @since 2.1
*/
- public static void writeLines(final File file, final Collection> lines, final String lineEnding,
- final boolean append) throws IOException {
+ public static void writeLines(final File file, final Collection> lines, final String lineEnding, final boolean append) throws IOException {
writeLines(file, null, lines, lineEnding, append);
}
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The specified character encoding and the default line ending will be used.
*
* NOTE: As from v1.3, the parent directories of the file will be created
@@ -3408,14 +3389,13 @@
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
* @since 1.1
*/
- public static void writeLines(final File file, final String charsetName, final Collection> lines)
- throws IOException {
+ public static void writeLines(final File file, final String charsetName, final Collection> lines) throws IOException {
writeLines(file, charsetName, lines, null, false);
}
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line, optionally appending.
+ * the specified {@link File} line by line, optionally appending.
* The specified character encoding and the default line ending will be used.
*
* @param file the file to write to
@@ -3427,14 +3407,13 @@
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
* @since 2.1
*/
- public static void writeLines(final File file, final String charsetName, final Collection> lines,
- final boolean append) throws IOException {
+ public static void writeLines(final File file, final String charsetName, final Collection> lines, final boolean append) throws IOException {
writeLines(file, charsetName, lines, null, append);
}
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The specified character encoding and the line ending will be used.
*
* NOTE: As from v1.3, the parent directories of the file will be created
@@ -3449,14 +3428,13 @@
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
* @since 1.1
*/
- public static void writeLines(final File file, final String charsetName, final Collection> lines,
- final String lineEnding) throws IOException {
+ public static void writeLines(final File file, final String charsetName, final Collection> lines, final String lineEnding) throws IOException {
writeLines(file, charsetName, lines, lineEnding, false);
}
/**
* Writes the {@code toString()} value of each item in a collection to
- * the specified {@code File} line by line.
+ * the specified {@link File} line by line.
* The specified character encoding and the line ending will be used.
*
* @param file the file to write to
@@ -3469,9 +3447,9 @@
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
* @since 2.1
*/
- public static void writeLines(final File file, final String charsetName, final Collection> lines,
- final String lineEnding, final boolean append) throws IOException {
- try (OutputStream out = new BufferedOutputStream(openOutputStream(file, append))) {
+ public static void writeLines(final File file, final String charsetName, final Collection> lines, final String lineEnding, final boolean append)
+ throws IOException {
+ try (OutputStream out = new BufferedOutputStream(newOutputStream(file, append))) {
IOUtils.writeLines(lines, lineEnding, out, charsetName);
}
}
@@ -3519,8 +3497,7 @@
* @throws java.io.UnsupportedEncodingException if the encoding is not supported by the VM
* @since 2.4
*/
- public static void writeStringToFile(final File file, final String data, final Charset charset)
- throws IOException {
+ public static void writeStringToFile(final File file, final String data, final Charset charset) throws IOException {
writeStringToFile(file, data, charset, false);
}
@@ -3535,9 +3512,8 @@
* @throws IOException in case of an I/O error
* @since 2.3
*/
- public static void writeStringToFile(final File file, final String data, final Charset charset,
- final boolean append) throws IOException {
- try (OutputStream out = openOutputStream(file, append)) {
+ public static void writeStringToFile(final File file, final String data, final Charset charset, final boolean append) throws IOException {
+ try (OutputStream out = newOutputStream(file, append)) {
IOUtils.write(data, out, charset);
}
}
@@ -3572,8 +3548,7 @@
* .UnsupportedEncodingException} in version 2.2 if the encoding is not supported by the VM
* @since 2.1
*/
- public static void writeStringToFile(final File file, final String data, final String charsetName,
- final boolean append) throws IOException {
+ public static void writeStringToFile(final File file, final String data, final String charsetName, final boolean append) throws IOException {
writeStringToFile(file, data, Charsets.toCharset(charsetName), append);
}
@@ -3585,4 +3560,5 @@
public FileUtils() { //NOSONAR
}
-}
\ No newline at end of file
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java (.../FilenameUtils.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/FilenameUtils.java (.../FilenameUtils.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -23,29 +23,34 @@
import java.util.Collection;
import java.util.Deque;
import java.util.List;
-import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Stream;
/**
* General file name and file path manipulation utilities.
*
* When dealing with file names you can hit problems when moving from a Windows
* based development machine to a Unix based production machine.
* This class aims to help avoid those problems.
+ *
*
* NOTE: You may be able to avoid using this class entirely simply by
* using JDK {@link java.io.File File} objects and the two argument constructor
- * {@link java.io.File#File(java.io.File, java.lang.String) File(File,String)}.
+ * {@link java.io.File#File(java.io.File, String) File(File,String)}.
+ *
*
* Most methods on this class are designed to work the same on both Unix and Windows.
* Those that don't include 'System', 'Unix' or 'Windows' in their name.
+ *
*
* Most methods recognize both separators (forward and back), and both
* sets of prefixes. See the Javadoc of each method for details.
+ *
*
* This class defines six components within a file name
* (example C:\dev\project\file.txt):
+ *
*
*
the prefix - C:\
*
the path - dev\project\
@@ -54,13 +59,16 @@
*
the base name - file
*
the extension - txt
*
+ *
* Note that this class works best if directory file names end with a separator.
* If you omit the last separator, it is impossible to determine if the file name
* corresponds to a file or a directory. As a result, we have chosen to say
* it corresponds to a file.
+ *
*
* This class only supports Unix and Windows style names.
* Prefixes are matched as follows:
+ *
*
* Windows:
* a\b\c.txt --> "" --> relative
@@ -77,10 +85,13 @@
* ~user/a/b/c.txt --> "~user/" --> named user
* ~user --> "~user/" --> named user (slash added)
*
+ *
* Both prefix styles are matched always, irrespective of the machine that you are
* currently running on.
+ *
*
* @since 1.1
*/
@@ -107,238 +118,199 @@
/**
* The Unix separator character.
*/
- private static final char UNIX_SEPARATOR = '/';
+ private static final char UNIX_NAME_SEPARATOR = '/';
/**
* The Windows separator character.
*/
- private static final char WINDOWS_SEPARATOR = '\\';
+ private static final char WINDOWS_NAME_SEPARATOR = '\\';
/**
* The system separator character.
*/
- private static final char SYSTEM_SEPARATOR = File.separatorChar;
+ private static final char SYSTEM_NAME_SEPARATOR = File.separatorChar;
/**
* The separator character that is the opposite of the system separator.
*/
- private static final char OTHER_SEPARATOR;
- static {
- if (isSystemWindows()) {
- OTHER_SEPARATOR = UNIX_SEPARATOR;
- } else {
- OTHER_SEPARATOR = WINDOWS_SEPARATOR;
- }
- }
+ private static final char OTHER_SEPARATOR = flipSeparator(SYSTEM_NAME_SEPARATOR);
- /**
- * Instances should NOT be constructed in standard programming.
- */
- public FilenameUtils() {
- }
+ private static final Pattern IPV4_PATTERN = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$");
- /**
- * Determines if Windows file system is in use.
- *
- * @return true if the system is Windows
- */
- static boolean isSystemWindows() {
- return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
- }
+ private static final int IPV4_MAX_OCTET_VALUE = 255;
- /**
- * Checks if the character is a separator.
- *
- * @param ch the character to check
- * @return true if it is a separator character
- */
- private static boolean isSeparator(final char ch) {
- return ch == UNIX_SEPARATOR || ch == WINDOWS_SEPARATOR;
- }
+ private static final int IPV6_MAX_HEX_GROUPS = 8;
+ private static final int IPV6_MAX_HEX_DIGITS_PER_GROUP = 4;
+
+ private static final int MAX_UNSIGNED_SHORT = 0xffff;
+
+ private static final int BASE_16 = 16;
+
+ private static final Pattern REG_NAME_PART_PATTERN = Pattern.compile("^[a-zA-Z0-9][a-zA-Z0-9-]*$");
+
/**
- * Normalizes a path, removing double and single dot path steps.
+ * Concatenates a fileName to a base path using normal command line style rules.
*
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format of the system.
+ * The effect is equivalent to resultant directory after changing
+ * directory to the first argument, followed by changing directory to
+ * the second argument.
+ *
*
- * A trailing slash will be retained.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with, {@code null}
- * is returned.
+ * The first argument is the base path, the second is the path to concatenate.
+ * The returned path is always normalized via {@link #normalize(String)},
+ * thus {@code ..} is handled.
+ *
*
+ * If {@code pathToAdd} is absolute (has an absolute prefix), then
+ * it will be normalized and returned.
+ * Otherwise, the paths will be joined, normalized and returned.
+ *
+ *
* The output will be the same on both Unix and Windows except
* for the separator character.
+ *
- * (Note the file separator returned will be correct for Windows/Unix)
+ *
+ * [1] Note that the Windows relative drive prefix is unreliable when
+ * used with this method.
+ *
+ *
+ * [2] Note that the first parameter must be a path. If it ends with a name, then
+ * the name will be built into the concatenated path. If this might be a problem,
+ * use {@link #getFullPath(String)} on the base path argument.
+ *
*
- * @param fileName the fileName to normalize, null returns null
- * @return the normalized fileName, or null if invalid. Null bytes inside string will be removed
+ * @param basePath the base path to attach to, always treated as a path
+ * @param fullFileNameToAdd the fileName (or path) to attach to the base
+ * @return the concatenated path, or null if invalid
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
*/
- public static String normalize(final String fileName) {
- return doNormalize(fileName, SYSTEM_SEPARATOR, true);
+ public static String concat(final String basePath, final String fullFileNameToAdd) {
+ final int prefix = getPrefixLength(fullFileNameToAdd);
+ if (prefix < 0) {
+ return null;
+ }
+ if (prefix > 0) {
+ return normalize(fullFileNameToAdd);
+ }
+ if (basePath == null) {
+ return null;
+ }
+ final int len = basePath.length();
+ if (len == 0) {
+ return normalize(fullFileNameToAdd);
+ }
+ final char ch = basePath.charAt(len - 1);
+ if (isSeparator(ch)) {
+ return normalize(basePath + fullFileNameToAdd);
+ }
+ return normalize(basePath + '/' + fullFileNameToAdd);
}
+
/**
- * Normalizes a path, removing double and single dot path steps.
+ * Determines whether the {@code parent} directory contains the {@code child} element (a file or directory).
*
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format specified.
- *
- * A trailing slash will be retained.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with, {@code null}
- * is returned.
- *
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * The output will be the same on both Unix and Windows including
- * the separator character.
+ * The files names are expected to be normalized.
+ *
*
- * @param fileName the fileName to normalize, null returns null
- * @param unixSeparator {@code true} if a unix separator should
- * be used or {@code false} if a windows separator should be used.
- * @return the normalized fileName, or null if invalid. Null bytes inside string will be removed
- * @since 2.0
+ * Edge cases:
+ *
+ *
A {@code directory} must not be null: if null, throw IllegalArgumentException
+ *
A directory does not contain itself: return false
+ *
A null child file is not contained in any parent: return false
+ *
+ *
+ * @param canonicalParent
+ * the file to consider as the parent.
+ * @param canonicalChild
+ * the file to consider as the child.
+ * @return true is the candidate leaf is under by the specified composite. False otherwise.
+ * @since 2.2
+ * @see FileUtils#directoryContains(File, File)
*/
- public static String normalize(final String fileName, final boolean unixSeparator) {
- final char separator = unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR;
- return doNormalize(fileName, separator, true);
+ public static boolean directoryContains(final String canonicalParent, final String canonicalChild) {
+ if (isEmpty(canonicalParent) || isEmpty(canonicalChild)) {
+ return false;
+ }
+
+ if (IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) {
+ return false;
+ }
+
+ final char separator = toSeparator(canonicalParent.charAt(0) == UNIX_NAME_SEPARATOR);
+ final String parentWithEndSeparator = canonicalParent.charAt(canonicalParent.length() - 1) == separator ? canonicalParent : canonicalParent + separator;
+
+ return IOCase.SYSTEM.checkStartsWith(canonicalChild, parentWithEndSeparator);
}
/**
- * Normalizes a path, removing double and single dot path steps,
- * and removing any final directory separator.
- *
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format of the system.
- *
- * A trailing slash will be removed.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with, {@code null}
- * is returned.
- *
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * (Note the file separator returned will be correct for Windows/Unix)
+ * Does the work of getting the path.
*
- * @param fileName the fileName to normalize, null returns null
- * @return the normalized fileName, or null if invalid. Null bytes inside string will be removed
+ * @param fileName the fileName
+ * @param includeSeparator true to include the end separator
+ * @return the path
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
*/
- public static String normalizeNoEndSeparator(final String fileName) {
- return doNormalize(fileName, SYSTEM_SEPARATOR, false);
+ private static String doGetFullPath(final String fileName, final boolean includeSeparator) {
+ if (fileName == null) {
+ return null;
+ }
+ final int prefix = getPrefixLength(fileName);
+ if (prefix < 0) {
+ return null;
+ }
+ if (prefix >= fileName.length()) {
+ if (includeSeparator) {
+ return getPrefix(fileName); // add end slash if necessary
+ }
+ return fileName;
+ }
+ final int index = indexOfLastSeparator(fileName);
+ if (index < 0) {
+ return fileName.substring(0, prefix);
+ }
+ int end = index + (includeSeparator ? 1 : 0);
+ if (end == 0) {
+ end++;
+ }
+ return fileName.substring(0, end);
}
/**
- * Normalizes a path, removing double and single dot path steps,
- * and removing any final directory separator.
- *
- * This method normalizes a path to a standard format.
- * The input may contain separators in either Unix or Windows format.
- * The output will contain separators in the format specified.
- *
- * A trailing slash will be removed.
- * A double slash will be merged to a single slash (but UNC names are handled).
- * A single dot path segment will be removed.
- * A double dot will cause that path segment and the one before to be removed.
- * If the double dot has no parent path segment to work with, {@code null}
- * is returned.
- *
- * The output will be the same on both Unix and Windows including
- * the separator character.
- *
+ * Does the work of getting the path.
*
- * @param fileName the fileName to normalize, null returns null
- * @param unixSeparator {@code true} if a unix separator should
- * be used or {@code false} if a windows separator should be used.
- * @return the normalized fileName, or null if invalid. Null bytes inside string will be removed
- * @since 2.0
+ * @param fileName the fileName
+ * @param separatorAdd 0 to omit the end separator, 1 to return it
+ * @return the path
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
*/
- public static String normalizeNoEndSeparator(final String fileName, final boolean unixSeparator) {
- final char separator = unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR;
- return doNormalize(fileName, separator, false);
+ private static String doGetPath(final String fileName, final int separatorAdd) {
+ if (fileName == null) {
+ return null;
+ }
+ final int prefix = getPrefixLength(fileName);
+ if (prefix < 0) {
+ return null;
+ }
+ final int index = indexOfLastSeparator(fileName);
+ final int endIndex = index + separatorAdd;
+ if (prefix >= fileName.length() || index < 0 || prefix >= endIndex) {
+ return EMPTY_STRING;
+ }
+ return requireNonNullChars(fileName.substring(prefix, endIndex));
}
/**
@@ -347,7 +319,8 @@
* @param fileName the fileName
* @param separator The separator character to use
* @param keepSeparator true to keep the final separator
- * @return the normalized fileName. Null bytes inside string will be removed.
+ * @return the normalized fileName
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
private static String doNormalize(final String fileName, final char separator, final boolean keepSeparator) {
if (fileName == null) {
@@ -369,7 +342,7 @@
fileName.getChars(0, fileName.length(), array, 0);
// fix separators throughout
- final char otherSeparator = separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR;
+ final char otherSeparator = flipSeparator(separator);
for (int i = 0; i < array.length; i++) {
if (array[i] == otherSeparator) {
array[i] = separator;
@@ -386,7 +359,7 @@
// adjoining slashes
// If we get here, prefix can only be 0 or greater, size 1 or greater
// If prefix is 0, set loop start to 1 to prevent index errors
- for (int i = (prefix != 0) ? prefix : 1; i < size; i++) {
+ for (int i = prefix != 0 ? prefix : 1; i < size; i++) {
if (array[i] == separator && array[i - 1] == separator) {
System.arraycopy(array, i, array, i - 1, size - i);
size--;
@@ -448,149 +421,413 @@
}
/**
- * Concatenates a fileName to a base path using normal command line style rules.
+ * Checks whether two fileNames are equal exactly.
*
- * The effect is equivalent to resultant directory after changing
- * directory to the first argument, followed by changing directory to
- * the second argument.
+ * No processing is performed on the fileNames other than comparison,
+ * thus this is merely a null-safe case-sensitive equals.
+ *
+ *
+ * @param fileName1 the first fileName to query, may be null
+ * @param fileName2 the second fileName to query, may be null
+ * @return true if the fileNames are equal, null equals null
+ * @see IOCase#SENSITIVE
+ */
+ public static boolean equals(final String fileName1, final String fileName2) {
+ return equals(fileName1, fileName2, false, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Checks whether two fileNames are equal, optionally normalizing and providing
+ * control over the case-sensitivity.
+ *
+ * @param fileName1 the first fileName to query, may be null
+ * @param fileName2 the second fileName to query, may be null
+ * @param normalize whether to normalize the fileNames
+ * @param ioCase what case sensitivity rule to use, null means case-sensitive
+ * @return true if the fileNames are equal, null equals null
+ * @since 1.3
+ */
+ public static boolean equals(String fileName1, String fileName2, final boolean normalize, final IOCase ioCase) {
+
+ if (fileName1 == null || fileName2 == null) {
+ return fileName1 == null && fileName2 == null;
+ }
+ if (normalize) {
+ fileName1 = normalize(fileName1);
+ if (fileName1 == null) {
+ return false;
+ }
+ fileName2 = normalize(fileName2);
+ if (fileName2 == null) {
+ return false;
+ }
+ }
+ return IOCase.value(ioCase, IOCase.SENSITIVE).checkEquals(fileName1, fileName2);
+ }
+
+ /**
+ * Checks whether two fileNames are equal after both have been normalized.
*
- * The first argument is the base path, the second is the path to concatenate.
- * The returned path is always normalized via {@link #normalize(String)},
- * thus {@code ..} is handled.
+ * Both fileNames are first passed to {@link #normalize(String)}.
+ * The check is then performed in a case-sensitive manner.
+ *
+ *
+ * @param fileName1 the first fileName to query, may be null
+ * @param fileName2 the second fileName to query, may be null
+ * @return true if the fileNames are equal, null equals null
+ * @see IOCase#SENSITIVE
+ */
+ public static boolean equalsNormalized(final String fileName1, final String fileName2) {
+ return equals(fileName1, fileName2, true, IOCase.SENSITIVE);
+ }
+
+ /**
+ * Checks whether two fileNames are equal after both have been normalized
+ * and using the case rules of the system.
*
- * If {@code pathToAdd} is absolute (has an absolute prefix), then
- * it will be normalized and returned.
- * Otherwise, the paths will be joined, normalized and returned.
+ * Both fileNames are first passed to {@link #normalize(String)}.
+ * The check is then performed case-sensitive on Unix and
+ * case-insensitive on Windows.
+ *
+ *
+ * @param fileName1 the first fileName to query, may be null
+ * @param fileName2 the second fileName to query, may be null
+ * @return true if the fileNames are equal, null equals null
+ * @see IOCase#SYSTEM
+ */
+ public static boolean equalsNormalizedOnSystem(final String fileName1, final String fileName2) {
+ return equals(fileName1, fileName2, true, IOCase.SYSTEM);
+ }
+
+ /**
+ * Checks whether two fileNames are equal using the case rules of the system.
*
- * The output will be the same on both Unix and Windows except
- * for the separator character.
- *
- * (*) Note that the Windows relative drive prefix is unreliable when
- * used with this method.
- * (!) Note that the first parameter must be a path. If it ends with a name, then
- * the name will be built into the concatenated path. If this might be a problem,
- * use {@link #getFullPath(String)} on the base path argument.
+ * No processing is performed on the fileNames other than comparison.
+ * The check is case-sensitive on Unix and case-insensitive on Windows.
+ *
*
- * @param basePath the base path to attach to, always treated as a path
- * @param fullFileNameToAdd the fileName (or path) to attach to the base
- * @return the concatenated path, or null if invalid. Null bytes inside string will be removed
+ * @param fileName1 the first fileName to query, may be null
+ * @param fileName2 the second fileName to query, may be null
+ * @return true if the fileNames are equal, null equals null
+ * @see IOCase#SYSTEM
*/
- public static String concat(final String basePath, final String fullFileNameToAdd) {
- final int prefix = getPrefixLength(fullFileNameToAdd);
- if (prefix < 0) {
- return null;
+ public static boolean equalsOnSystem(final String fileName1, final String fileName2) {
+ return equals(fileName1, fileName2, false, IOCase.SYSTEM);
+ }
+
+ /**
+ * Flips the Windows name separator to Linux and vice-versa.
+ *
+ * @param ch The Windows or Linux name separator.
+ * @return The Windows or Linux name separator.
+ */
+ static char flipSeparator(final char ch) {
+ if (ch == UNIX_NAME_SEPARATOR) {
+ return WINDOWS_NAME_SEPARATOR;
}
- if (prefix > 0) {
- return normalize(fullFileNameToAdd);
+ if (ch == WINDOWS_NAME_SEPARATOR) {
+ return UNIX_NAME_SEPARATOR;
}
- if (basePath == null) {
- return null;
+ throw new IllegalArgumentException(String.valueOf(ch));
+ }
+
+ /**
+ * Special handling for NTFS ADS: Don't accept colon in the fileName.
+ *
+ * @param fileName a file name
+ * @return ADS offsets.
+ */
+ private static int getAdsCriticalOffset(final String fileName) {
+ // Step 1: Remove leading path segments.
+ final int offset1 = fileName.lastIndexOf(SYSTEM_NAME_SEPARATOR);
+ final int offset2 = fileName.lastIndexOf(OTHER_SEPARATOR);
+ if (offset1 == -1) {
+ if (offset2 == -1) {
+ return 0;
+ }
+ return offset2 + 1;
}
- final int len = basePath.length();
- if (len == 0) {
- return normalize(fullFileNameToAdd);
+ if (offset2 == -1) {
+ return offset1 + 1;
}
- final char ch = basePath.charAt(len - 1);
- if (isSeparator(ch)) {
- return normalize(basePath + fullFileNameToAdd);
- }
- return normalize(basePath + '/' + fullFileNameToAdd);
+ return Math.max(offset1, offset2) + 1;
}
/**
- * Determines whether the {@code parent} directory contains the {@code child} element (a file or directory).
+ * Gets the base name, minus the full path and extension, from a full fileName.
*
- * The files names are expected to be normalized.
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash and before the last dot is returned.
*
+ *
+ * a/b/c.txt --> c
+ * a.txt --> a
+ * a/b/c --> c
+ * a/b/c/ --> ""
+ *
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
*
- * Edge cases:
- *
- *
A {@code directory} must not be null: if null, throw IllegalArgumentException
- *
A directory does not contain itself: return false
- *
A null child file is not contained in any parent: return false
- *
- *
- * @param canonicalParent
- * the file to consider as the parent.
- * @param canonicalChild
- * the file to consider as the child.
- * @return true is the candidate leaf is under by the specified composite. False otherwise.
- * @since 2.2
- * @see FileUtils#directoryContains(File, File)
+ * @param fileName the fileName to query, null returns null
+ * @return the name of the file without the path, or an empty string if none exists
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static boolean directoryContains(final String canonicalParent, final String canonicalChild) {
- Objects.requireNonNull(canonicalParent, "canonicalParent");
+ public static String getBaseName(final String fileName) {
+ return removeExtension(getName(fileName));
+ }
- if (canonicalChild == null) {
- return false;
+ /**
+ * Gets the extension of a fileName.
+ *
+ * This method returns the textual part of the fileName after the last dot.
+ * There must be no directory separator after the dot.
+ *
+ * The output will be the same irrespective of the machine that the code is running on, with the
+ * exception of a possible {@link IllegalArgumentException} on Windows (see below).
+ *
+ *
+ * Note: This method used to have a hidden problem for names like "foo.exe:bar.txt".
+ * In this case, the name wouldn't be the name of a file, but the identifier of an
+ * alternate data stream (bar.txt) on the file foo.exe. The method used to return
+ * ".txt" here, which would be misleading. Commons IO 2.7, and later versions, are throwing
+ * an {@link IllegalArgumentException} for names like this.
+ *
+ *
+ * @param fileName the fileName to retrieve the extension of.
+ * @return the extension of the file or an empty string if none exists or {@code null}
+ * if the fileName is {@code null}.
+ * @throws IllegalArgumentException Windows only: The fileName parameter is, in fact,
+ * the identifier of an Alternate Data Stream, for example "foo.exe:bar.txt".
+ */
+ public static String getExtension(final String fileName) throws IllegalArgumentException {
+ if (fileName == null) {
+ return null;
}
-
- if (IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) {
- return false;
+ final int index = indexOfExtension(fileName);
+ if (index == NOT_FOUND) {
+ return EMPTY_STRING;
}
+ return fileName.substring(index + 1);
+ }
- return IOCase.SYSTEM.checkStartsWith(canonicalChild, canonicalParent);
+ /**
+ * Gets the full path from a full fileName, which is the prefix + path.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before and
+ * including the last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ *
+ * @param fileName the fileName to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
+ */
+ public static String getFullPath(final String fileName) {
+ return doGetFullPath(fileName, true);
}
/**
- * Converts all separators to the Unix separator of forward slash.
+ * Gets the full path from a full fileName, which is the prefix + path,
+ * and also excluding the final directory separator.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before the
+ * last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
*
- * @param path the path to be changed, null ignored
- * @return the updated path
+ * @param fileName the fileName to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
*/
- public static String separatorsToUnix(final String path) {
- if (path == null || path.indexOf(WINDOWS_SEPARATOR) == NOT_FOUND) {
- return path;
- }
- return path.replace(WINDOWS_SEPARATOR, UNIX_SEPARATOR);
+ public static String getFullPathNoEndSeparator(final String fileName) {
+ return doGetFullPath(fileName, false);
}
/**
- * Converts all separators to the Windows separator of backslash.
+ * Gets the name minus the path from a full fileName.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The text after the last forward or backslash is returned.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
*
- * @param path the path to be changed, null ignored
- * @return the updated path
+ * @param fileName the fileName to query, null returns null
+ * @return the name of the file without the path, or an empty string if none exists
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static String separatorsToWindows(final String path) {
- if (path == null || path.indexOf(UNIX_SEPARATOR) == NOT_FOUND) {
- return path;
+ public static String getName(final String fileName) {
+ if (fileName == null) {
+ return null;
}
- return path.replace(UNIX_SEPARATOR, WINDOWS_SEPARATOR);
+ return requireNonNullChars(fileName).substring(indexOfLastSeparator(fileName) + 1);
}
/**
- * Converts all separators to the system separator.
+ * Gets the path from a full fileName, which excludes the prefix.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before and
+ * including the last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ *
+ * This method drops the prefix from the result.
+ * See {@link #getFullPath(String)} for the method that retains the prefix.
+ *
*
- * @param path the path to be changed, null ignored
- * @return the updated path
+ * @param fileName the fileName to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
*/
- public static String separatorsToSystem(final String path) {
- if (path == null) {
+ public static String getPath(final String fileName) {
+ return doGetPath(fileName, 1);
+ }
+
+ /**
+ * Gets the path from a full fileName, which excludes the prefix, and
+ * also excluding the final directory separator.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The method is entirely text based, and returns the text before the
+ * last forward or backslash.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ *
+ *
+ * This method drops the prefix from the result.
+ * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix.
+ *
+ *
+ * @param fileName the fileName to query, null returns null
+ * @return the path of the file, an empty string if none exists, null if invalid
+ * @throws IllegalArgumentException if the result path contains the null character ({@code U+0000})
+ */
+ public static String getPathNoEndSeparator(final String fileName) {
+ return doGetPath(fileName, 0);
+ }
+
+ /**
+ * Gets the prefix from a full fileName, such as {@code C:/}
+ * or {@code ~/}.
+ *
+ * This method will handle a file in either Unix or Windows format.
+ * The prefix includes the first slash in the full fileName where applicable.
+ *
+ * The output will be the same irrespective of the machine that the code is running on.
+ * ie. both Unix and Windows prefixes are matched regardless.
+ *
+ *
+ * @param fileName the fileName to query, null returns null
+ * @return the prefix of the file, null if invalid
+ * @throws IllegalArgumentException if the result contains the null character ({@code U+0000})
+ */
+ public static String getPrefix(final String fileName) {
+ if (fileName == null) {
return null;
}
- return isSystemWindows() ? separatorsToWindows(path) : separatorsToUnix(path);
+ final int len = getPrefixLength(fileName);
+ if (len < 0) {
+ return null;
+ }
+ if (len > fileName.length()) {
+ requireNonNullChars(fileName);
+ return fileName + UNIX_NAME_SEPARATOR;
+ }
+ return requireNonNullChars(fileName.substring(0, len));
}
/**
* Returns the length of the fileName prefix, such as {@code C:/} or {@code ~/}.
*
* This method will handle a file in either Unix or Windows format.
+ *
*
* The prefix length includes the first slash in the full fileName
* if applicable. Thus, it is possible that the length returned is greater
* than the length of the input string.
+ *
*
* Windows:
* a\b\c.txt --> 0 --> relative
@@ -609,15 +846,17 @@
* ~user --> 6 --> named user (slash added)
* //server/a/b/c.txt --> 9
* ///a/b/c.txt --> -1 --> error
- * C: --> 0 --> valid filename as only null byte and / are reserved characters
+ * C: --> 0 --> valid file name as only null character and / are reserved characters
*
*
* The output will be the same irrespective of the machine that the code is running on.
* ie. both Unix and Windows prefixes are matched regardless.
- *
+ *
+ *
* Note that a leading // (or \\) is used to indicate a UNC name on Windows.
* These must be followed by a server name, so double-slashes are not collapsed
* to a single slash at the start of the fileName.
+ *
*
* @param fileName the fileName to find the prefix in, null returns -1
* @return the length of the prefix, -1 if invalid or null
@@ -641,8 +880,8 @@
return isSeparator(ch0) ? 1 : 0;
}
if (ch0 == '~') {
- int posUnix = fileName.indexOf(UNIX_SEPARATOR, 1);
- int posWin = fileName.indexOf(WINDOWS_SEPARATOR, 1);
+ int posUnix = fileName.indexOf(UNIX_NAME_SEPARATOR, 1);
+ int posWin = fileName.indexOf(WINDOWS_NAME_SEPARATOR, 1);
if (posUnix == NOT_FOUND && posWin == NOT_FOUND) {
return len + 1; // return a length greater than the input
}
@@ -662,7 +901,7 @@
}
return 3;
}
- if (ch0 == UNIX_SEPARATOR) {
+ if (ch0 == UNIX_NAME_SEPARATOR) {
return 1;
}
return NOT_FOUND;
@@ -671,8 +910,8 @@
if (!isSeparator(ch0) || !isSeparator(ch1)) {
return isSeparator(ch0) ? 1 : 0;
}
- int posUnix = fileName.indexOf(UNIX_SEPARATOR, 2);
- int posWin = fileName.indexOf(WINDOWS_SEPARATOR, 2);
+ int posUnix = fileName.indexOf(UNIX_NAME_SEPARATOR, 2);
+ int posWin = fileName.indexOf(WINDOWS_NAME_SEPARATOR, 2);
if (posUnix == NOT_FOUND && posWin == NOT_FOUND || posUnix == 2 || posWin == 2) {
return NOT_FOUND;
}
@@ -684,27 +923,6 @@
}
/**
- * Returns the index of the last directory separator character.
- *
- * This method will handle a file in either Unix or Windows format.
- * The position of the last forward or backslash is returned.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * @param fileName the fileName to find the last path separator in, null returns -1
- * @return the index of the last separator character, or -1 if there
- * is no such character
- */
- public static int indexOfLastSeparator(final String fileName) {
- if (fileName == null) {
- return NOT_FOUND;
- }
- final int lastUnixPos = fileName.lastIndexOf(UNIX_SEPARATOR);
- final int lastWindowsPos = fileName.lastIndexOf(WINDOWS_SEPARATOR);
- return Math.max(lastUnixPos, lastWindowsPos);
- }
-
- /**
* Returns the index of the last extension separator character, which is a dot.
*
* This method also checks that there is no directory separator after the last dot. To do this it uses
@@ -743,344 +961,443 @@
}
/**
- * Gets the prefix from a full fileName, such as {@code C:/}
- * or {@code ~/}.
+ * Returns the index of the last directory separator character.
*
* This method will handle a file in either Unix or Windows format.
- * The prefix includes the first slash in the full fileName where applicable.
- *
+ * The position of the last forward or backslash is returned.
*
* The output will be the same irrespective of the machine that the code is running on.
- * ie. both Unix and Windows prefixes are matched regardless.
*
- * @param fileName the fileName to query, null returns null
- * @return the prefix of the file, null if invalid. Null bytes inside string will be removed
+ * @param fileName the fileName to find the last path separator in, null returns -1
+ * @return the index of the last separator character, or -1 if there
+ * is no such character
*/
- public static String getPrefix(final String fileName) {
+ public static int indexOfLastSeparator(final String fileName) {
if (fileName == null) {
- return null;
+ return NOT_FOUND;
}
- final int len = getPrefixLength(fileName);
- if (len < 0) {
- return null;
- }
- if (len > fileName.length()) {
- requireNonNullChars(fileName + UNIX_SEPARATOR);
- return fileName + UNIX_SEPARATOR;
- }
- final String path = fileName.substring(0, len);
- requireNonNullChars(path);
- return path;
+ final int lastUnixPos = fileName.lastIndexOf(UNIX_NAME_SEPARATOR);
+ final int lastWindowsPos = fileName.lastIndexOf(WINDOWS_NAME_SEPARATOR);
+ return Math.max(lastUnixPos, lastWindowsPos);
}
- /**
- * Gets the path from a full fileName, which excludes the prefix.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before and
- * including the last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * This method drops the prefix from the result.
- * See {@link #getFullPath(String)} for the method that retains the prefix.
- *
- * @param fileName the fileName to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid.
- * Null bytes inside string will be removed
- */
- public static String getPath(final String fileName) {
- return doGetPath(fileName, 1);
+ private static boolean isEmpty(final String string) {
+ return string == null || string.isEmpty();
}
/**
- * Gets the path from a full fileName, which excludes the prefix, and
- * also excluding the final directory separator.
+ * Checks whether the extension of the fileName is one of those specified.
*
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before the
- * last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
- *
- * This method drops the prefix from the result.
- * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix.
+ * This method obtains the extension as the textual part of the fileName
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
*
- * @param fileName the fileName to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid.
- * Null bytes inside string will be removed
+ * @param fileName the fileName to query, null returns false
+ * @param extensions the extensions to check for, null checks for no extension
+ * @return true if the fileName is one of the extensions
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static String getPathNoEndSeparator(final String fileName) {
- return doGetPath(fileName, 0);
+ public static boolean isExtension(final String fileName, final Collection extensions) {
+ if (fileName == null) {
+ return false;
+ }
+ requireNonNullChars(fileName);
+
+ if (extensions == null || extensions.isEmpty()) {
+ return indexOfExtension(fileName) == NOT_FOUND;
+ }
+ return extensions.contains(getExtension(fileName));
}
/**
- * Does the work of getting the path.
+ * Checks whether the extension of the fileName is that specified.
+ *
+ * This method obtains the extension as the textual part of the fileName
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
*
- * @param fileName the fileName
- * @param separatorAdd 0 to omit the end separator, 1 to return it
- * @return the path. Null bytes inside string will be removed
+ * @param fileName the fileName to query, null returns false
+ * @param extension the extension to check for, null or empty checks for no extension
+ * @return true if the fileName has the specified extension
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- private static String doGetPath(final String fileName, final int separatorAdd) {
+ public static boolean isExtension(final String fileName, final String extension) {
if (fileName == null) {
- return null;
+ return false;
}
- final int prefix = getPrefixLength(fileName);
- if (prefix < 0) {
- return null;
+ requireNonNullChars(fileName);
+
+ if (isEmpty(extension)) {
+ return indexOfExtension(fileName) == NOT_FOUND;
}
- final int index = indexOfLastSeparator(fileName);
- final int endIndex = index+separatorAdd;
- if (prefix >= fileName.length() || index < 0 || prefix >= endIndex) {
- return EMPTY_STRING;
- }
- final String path = fileName.substring(prefix, endIndex);
- requireNonNullChars(path);
- return path;
+ return getExtension(fileName).equals(extension);
}
/**
- * Gets the full path from a full fileName, which is the prefix + path.
+ * Checks whether the extension of the fileName is one of those specified.
*
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before and
- * including the last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
+ * This method obtains the extension as the textual part of the fileName
+ * after the last dot. There must be no directory separator after the dot.
+ * The extension check is case-sensitive on all platforms.
*
- * @param fileName the fileName to query, null returns null
- * @return the path of the file, an empty string if none exists, null if invalid
+ * @param fileName the fileName to query, null returns false
+ * @param extensions the extensions to check for, null checks for no extension
+ * @return true if the fileName is one of the extensions
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static String getFullPath(final String fileName) {
- return doGetFullPath(fileName, true);
+ public static boolean isExtension(final String fileName, final String... extensions) {
+ if (fileName == null) {
+ return false;
+ }
+ requireNonNullChars(fileName);
+
+ if (extensions == null || extensions.length == 0) {
+ return indexOfExtension(fileName) == NOT_FOUND;
+ }
+ final String fileExt = getExtension(fileName);
+ return Stream.of(extensions).anyMatch(fileExt::equals);
}
/**
- * Gets the full path from a full fileName, which is the prefix + path,
- * and also excluding the final directory separator.
- *
- * This method will handle a file in either Unix or Windows format.
- * The method is entirely text based, and returns the text before the
- * last forward or backslash.
- *
- * The output will be the same irrespective of the machine that the code is running on.
+ * Checks whether a given string is a valid host name according to
+ * RFC 3986 - not accepting IP addresses.
*
- * @param fileName the fileName to query, null returns null
- * @return the name of the file without the path, or an empty string if none exists.
- * Null bytes inside string will be removed
+ * @see "https://tools.ietf.org/html/rfc3986#section-3.2.2"
+ * @param name the hostname to validate
+ * @return true if the given name is a valid host name
*/
- public static String getName(final String fileName) {
- if (fileName == null) {
- return null;
+ private static boolean isRFC3986HostName(final String name) {
+ final String[] parts = name.split("\\.", -1);
+ for (int i = 0; i < parts.length; i++) {
+ if (parts[i].isEmpty()) {
+ // trailing dot is legal, otherwise we've hit a .. sequence
+ return i == parts.length - 1;
+ }
+ if (!REG_NAME_PART_PATTERN.matcher(parts[i]).matches()) {
+ return false;
+ }
}
- requireNonNullChars(fileName);
- final int index = indexOfLastSeparator(fileName);
- return fileName.substring(index + 1);
+ return true;
}
/**
- * Checks the input for null bytes, a sign of unsanitized data being passed to to file level functions.
+ * Checks if the character is a separator.
*
- * This may be used for poison byte attacks.
+ * @param ch the character to check
+ * @return true if it is a separator character
+ */
+ private static boolean isSeparator(final char ch) {
+ return ch == UNIX_NAME_SEPARATOR || ch == WINDOWS_NAME_SEPARATOR;
+ }
+
+ /**
+ * Determines if Windows file system is in use.
*
- * @param path the path to check
+ * @return true if the system is Windows
*/
- private static void requireNonNullChars(final String path) {
- if (path.indexOf(0) >= 0) {
- throw new IllegalArgumentException("Null byte present in file/path name. There are no "
- + "known legitimate use cases for such data, but several injection attacks may use it");
- }
+ static boolean isSystemWindows() {
+ return SYSTEM_NAME_SEPARATOR == WINDOWS_NAME_SEPARATOR;
}
/**
- * Gets the base name, minus the full path and extension, from a full fileName.
+ * Checks whether a given string is a valid host name according to
+ * RFC 3986.
+ *
+ *
Accepted are IP addresses (v4 and v6) as well as what the
+ * RFC calls a "reg-name". Percent encoded names don't seem to be
+ * valid names in UNC paths.
+ *
+ * @see "https://tools.ietf.org/html/rfc3986#section-3.2.2"
+ * @param name the hostname to validate
+ * @return true if the given name is a valid host name
+ */
+ private static boolean isValidHostName(final String name) {
+ return isIPv6Address(name) || isRFC3986HostName(name);
+ }
+
+ /**
+ * Normalizes a path, removing double and single dot path steps.
*
- * This method will handle a file in either Unix or Windows format.
- * The text after the last forward or backslash and before the last dot is returned.
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format of the system.
+ *
+ * A trailing slash will be retained.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with, {@code null}
+ * is returned.
+ *
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
*
- * The output will be the same irrespective of the machine that the code is running on.
+ * (Note the file separator returned will be correct for Windows/Unix)
*
- * @param fileName the fileName to query, null returns null
- * @return the name of the file without the path, or an empty string if none exists. Null bytes inside string
- * will be removed
+ * @param fileName the fileName to normalize, null returns null
+ * @return the normalized fileName, or null if invalid
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static String getBaseName(final String fileName) {
- return removeExtension(getName(fileName));
+ public static String normalize(final String fileName) {
+ return doNormalize(fileName, SYSTEM_NAME_SEPARATOR, true);
}
/**
- * Gets the extension of a fileName.
+ * Normalizes a path, removing double and single dot path steps.
*
- * This method returns the textual part of the fileName after the last dot.
- * There must be no directory separator after the dot.
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format specified.
+ *
+ * A trailing slash will be retained.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with, {@code null}
+ * is returned.
+ *
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
*
+ * The output will be the same on both Unix and Windows including
+ * the separator character.
+ *
+ * @param fileName the fileName to normalize, null returns null
+ * @param unixSeparator {@code true} if a Unix separator should
+ * be used or {@code false} if a Windows separator should be used.
+ * @return the normalized fileName, or null if invalid
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
+ * @since 2.0
+ */
+ public static String normalize(final String fileName, final boolean unixSeparator) {
+ return doNormalize(fileName, toSeparator(unixSeparator), true);
+ }
+
+ /**
+ * Normalizes a path, removing double and single dot path steps,
+ * and removing any final directory separator.
*
- * The output will be the same irrespective of the machine that the code is running on, with the
- * exception of a possible {@link IllegalArgumentException} on Windows (see below).
- *
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format of the system.
*
- * Note: This method used to have a hidden problem for names like "foo.exe:bar.txt".
- * In this case, the name wouldn't be the name of a file, but the identifier of an
- * alternate data stream (bar.txt) on the file foo.exe. The method used to return
- * ".txt" here, which would be misleading. Commons IO 2.7, and later versions, are throwing
- * an {@link IllegalArgumentException} for names like this.
+ * A trailing slash will be removed.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with, {@code null}
+ * is returned.
+ *
+ * The output will be the same on both Unix and Windows except
+ * for the separator character.
+ *
+ * (Note the file separator returned will be correct for Windows/Unix)
*
- * @param fileName the fileName to retrieve the extension of.
- * @return the extension of the file or an empty string if none exists or {@code null}
- * if the fileName is {@code null}.
- * @throws IllegalArgumentException Windows only: The fileName parameter is, in fact,
- * the identifier of an Alternate Data Stream, for example "foo.exe:bar.txt".
+ * @param fileName the fileName to normalize, null returns null
+ * @return the normalized fileName, or null if invalid
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
- public static String getExtension(final String fileName) throws IllegalArgumentException {
- if (fileName == null) {
- return null;
- }
- final int index = indexOfExtension(fileName);
- if (index == NOT_FOUND) {
- return EMPTY_STRING;
- }
- return fileName.substring(index + 1);
+ public static String normalizeNoEndSeparator(final String fileName) {
+ return doNormalize(fileName, SYSTEM_NAME_SEPARATOR, false);
}
/**
- * Special handling for NTFS ADS: Don't accept colon in the fileName.
+ * Normalizes a path, removing double and single dot path steps,
+ * and removing any final directory separator.
+ *
+ * This method normalizes a path to a standard format.
+ * The input may contain separators in either Unix or Windows format.
+ * The output will contain separators in the format specified.
+ *
+ * A trailing slash will be removed.
+ * A double slash will be merged to a single slash (but UNC names are handled).
+ * A single dot path segment will be removed.
+ * A double dot will cause that path segment and the one before to be removed.
+ * If the double dot has no parent path segment to work with, {@code null}
+ * is returned.
+ *
+ * The output will be the same on both Unix and Windows including
+ * the separator character.
+ *
*
- * @param fileName a file name
- * @return ADS offsets.
+ * @param fileName the fileName to normalize, null returns null
+ * @param unixSeparator {@code true} if a Unix separator should
+ * be used or {@code false} if a Windows separator should be used.
+ * @return the normalized fileName, or null if invalid
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
+ * @since 2.0
*/
- private static int getAdsCriticalOffset(final String fileName) {
- // Step 1: Remove leading path segments.
- final int offset1 = fileName.lastIndexOf(SYSTEM_SEPARATOR);
- final int offset2 = fileName.lastIndexOf(OTHER_SEPARATOR);
- if (offset1 == -1) {
- if (offset2 == -1) {
- return 0;
- }
- return offset2 + 1;
- }
- if (offset2 == -1) {
- return offset1 + 1;
- }
- return Math.max(offset1, offset2) + 1;
+ public static String normalizeNoEndSeparator(final String fileName, final boolean unixSeparator) {
+ return doNormalize(fileName, toSeparator(unixSeparator), false);
}
/**
@@ -1099,6 +1416,7 @@
*
* @param fileName the fileName to query, null returns null
* @return the fileName minus the extension
+ * @throws IllegalArgumentException if the fileName contains the null character ({@code U+0000})
*/
public static String removeExtension(final String fileName) {
if (fileName == null) {
@@ -1114,193 +1432,112 @@
}
/**
- * Checks whether two fileNames are equal exactly.
- *
- * No processing is performed on the fileNames other than comparison,
- * thus this is merely a null-safe case-sensitive equals.
+ * Checks the input for null characters ({@code U+0000}), a sign of unsanitized data being passed to file level functions.
*
- * @param fileName1 the first fileName to query, may be null
- * @param fileName2 the second fileName to query, may be null
- * @return true if the fileNames are equal, null equals null
- * @see IOCase#SENSITIVE
+ * This may be used for poison byte attacks.
+ *
+ * @param path the path to check
+ * @return The input
+ * @throws IllegalArgumentException if path contains the null character ({@code U+0000})
*/
- public static boolean equals(final String fileName1, final String fileName2) {
- return equals(fileName1, fileName2, false, IOCase.SENSITIVE);
+ private static String requireNonNullChars(final String path) {
+ if (path.indexOf(0) >= 0) {
+ throw new IllegalArgumentException(
+ "Null character present in file/path name. There are no known legitimate use cases for such data, but several injection attacks may use it");
+ }
+ return path;
}
/**
- * Checks whether two fileNames are equal using the case rules of the system.
- *
- * No processing is performed on the fileNames other than comparison.
- * The check is case-sensitive on Unix and case-insensitive on Windows.
+ * Converts all separators to the system separator.
*
- * @param fileName1 the first fileName to query, may be null
- * @param fileName2 the second fileName to query, may be null
- * @return true if the fileNames are equal, null equals null
- * @see IOCase#SYSTEM
+ * @param path the path to be changed, null ignored.
+ * @return the updated path.
*/
- public static boolean equalsOnSystem(final String fileName1, final String fileName2) {
- return equals(fileName1, fileName2, false, IOCase.SYSTEM);
+ public static String separatorsToSystem(final String path) {
+ return FileSystem.getCurrent().normalizeSeparators(path);
}
/**
- * Checks whether two fileNames are equal after both have been normalized.
- *
- * Both fileNames are first passed to {@link #normalize(String)}.
- * The check is then performed in a case-sensitive manner.
+ * Converts all separators to the Unix separator of forward slash.
*
- * @param fileName1 the first fileName to query, may be null
- * @param fileName2 the second fileName to query, may be null
- * @return true if the fileNames are equal, null equals null
- * @see IOCase#SENSITIVE
+ * @param path the path to be changed, null ignored.
+ * @return the new path.
*/
- public static boolean equalsNormalized(final String fileName1, final String fileName2) {
- return equals(fileName1, fileName2, true, IOCase.SENSITIVE);
+ public static String separatorsToUnix(final String path) {
+ return FileSystem.LINUX.normalizeSeparators(path);
}
/**
- * Checks whether two fileNames are equal after both have been normalized
- * and using the case rules of the system.
- *
- * Both fileNames are first passed to {@link #normalize(String)}.
- * The check is then performed case-sensitive on Unix and
- * case-insensitive on Windows.
+ * Converts all separators to the Windows separator of backslash.
*
- * @param fileName1 the first fileName to query, may be null
- * @param fileName2 the second fileName to query, may be null
- * @return true if the fileNames are equal, null equals null
- * @see IOCase#SYSTEM
+ * @param path the path to be changed, null ignored.
+ * @return the updated path.
*/
- public static boolean equalsNormalizedOnSystem(final String fileName1, final String fileName2) {
- return equals(fileName1, fileName2, true, IOCase.SYSTEM);
+ public static String separatorsToWindows(final String path) {
+ return FileSystem.WINDOWS.normalizeSeparators(path);
}
/**
- * Checks whether two fileNames are equal, optionally normalizing and providing
- * control over the case-sensitivity.
+ * Splits a string into a number of tokens.
+ * The text is split by '?' and '*'.
+ * Where multiple '*' occur consecutively they are collapsed into a single '*'.
*
- * @param fileName1 the first fileName to query, may be null
- * @param fileName2 the second fileName to query, may be null
- * @param normalized whether to normalize the fileNames
- * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
- * @return true if the fileNames are equal, null equals null
- * @since 1.3
+ * @param text the text to split
+ * @return the array of tokens, never null
*/
- public static boolean equals(
- String fileName1, String fileName2,
- final boolean normalized, IOCase caseSensitivity) {
+ static String[] splitOnTokens(final String text) {
+ // used by wildcardMatch
+ // package level so a unit test may run on this
- if (fileName1 == null || fileName2 == null) {
- return fileName1 == null && fileName2 == null;
+ if (text.indexOf('?') == NOT_FOUND && text.indexOf('*') == NOT_FOUND) {
+ return new String[] { text };
}
- if (normalized) {
- fileName1 = normalize(fileName1);
- if (fileName1 == null) {
- return false;
+
+ final char[] array = text.toCharArray();
+ final ArrayList list = new ArrayList<>();
+ final StringBuilder buffer = new StringBuilder();
+ char prevChar = 0;
+ for (final char ch : array) {
+ if (ch == '?' || ch == '*') {
+ if (buffer.length() != 0) {
+ list.add(buffer.toString());
+ buffer.setLength(0);
+ }
+ if (ch == '?') {
+ list.add("?");
+ } else if (prevChar != '*') {// ch == '*' here; check if previous char was '*'
+ list.add("*");
+ }
+ } else {
+ buffer.append(ch);
}
- fileName2 = normalize(fileName2);
- if (fileName2 == null) {
- return false;
- }
+ prevChar = ch;
}
- if (caseSensitivity == null) {
- caseSensitivity = IOCase.SENSITIVE;
+ if (buffer.length() != 0) {
+ list.add(buffer.toString());
}
- return caseSensitivity.checkEquals(fileName1, fileName2);
- }
- /**
- * Checks whether the extension of the fileName is that specified.
- *
- * This method obtains the extension as the textual part of the fileName
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
- *
- * @param fileName the fileName to query, null returns false
- * @param extension the extension to check for, null or empty checks for no extension
- * @return true if the fileName has the specified extension
- * @throws java.lang.IllegalArgumentException if the supplied fileName contains null bytes
- */
- public static boolean isExtension(final String fileName, final String extension) {
- if (fileName == null) {
- return false;
- }
- requireNonNullChars(fileName);
-
- if (extension == null || extension.isEmpty()) {
- return indexOfExtension(fileName) == NOT_FOUND;
- }
- final String fileExt = getExtension(fileName);
- return fileExt.equals(extension);
+ return list.toArray(EMPTY_STRING_ARRAY);
}
/**
- * Checks whether the extension of the fileName is one of those specified.
- *
- * This method obtains the extension as the textual part of the fileName
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
+ * Returns '/' if given true, '\\' otherwise.
*
- * @param fileName the fileName to query, null returns false
- * @param extensions the extensions to check for, null checks for no extension
- * @return true if the fileName is one of the extensions
- * @throws java.lang.IllegalArgumentException if the supplied fileName contains null bytes
+ * @param unixSeparator which separator to return.
+ * @return '/' if given true, '\\' otherwise.
*/
- public static boolean isExtension(final String fileName, final String... extensions) {
- if (fileName == null) {
- return false;
- }
- requireNonNullChars(fileName);
-
- if (extensions == null || extensions.length == 0) {
- return indexOfExtension(fileName) == NOT_FOUND;
- }
- final String fileExt = getExtension(fileName);
- for (final String extension : extensions) {
- if (fileExt.equals(extension)) {
- return true;
- }
- }
- return false;
+ private static char toSeparator(final boolean unixSeparator) {
+ return unixSeparator ? UNIX_NAME_SEPARATOR : WINDOWS_NAME_SEPARATOR;
}
/**
- * Checks whether the extension of the fileName is one of those specified.
- *
- * This method obtains the extension as the textual part of the fileName
- * after the last dot. There must be no directory separator after the dot.
- * The extension check is case-sensitive on all platforms.
- *
- * @param fileName the fileName to query, null returns false
- * @param extensions the extensions to check for, null checks for no extension
- * @return true if the fileName is one of the extensions
- * @throws java.lang.IllegalArgumentException if the supplied fileName contains null bytes
- */
- public static boolean isExtension(final String fileName, final Collection extensions) {
- if (fileName == null) {
- return false;
- }
- requireNonNullChars(fileName);
-
- if (extensions == null || extensions.isEmpty()) {
- return indexOfExtension(fileName) == NOT_FOUND;
- }
- final String fileExt = getExtension(fileName);
- for (final String extension : extensions) {
- if (fileExt.equals(extension)) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Checks a fileName to see if it matches the specified wildcard matcher,
* always testing case-sensitive.
*
* The wildcard matcher uses the characters '?' and '*' to represent a
* single or multiple (zero or more) wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
+ * This is the same as often found on DOS/Unix command lines.
* The check is case-sensitive always.
*
* wildcardMatch("c.txt", "*.txt") --> true
@@ -1322,32 +1559,6 @@
/**
* Checks a fileName to see if it matches the specified wildcard matcher
- * using the case rules of the system.
- *
- * The wildcard matcher uses the characters '?' and '*' to represent a
- * single or multiple (zero or more) wildcard characters.
- * This is the same as often found on Dos/Unix command lines.
- * The check is case-sensitive on Unix and case-insensitive on Windows.
- *
- * N.B. the sequence "*?" does not work properly at present in match strings.
- *
- * @param fileName the fileName to match on
- * @param wildcardMatcher the wildcard string to match against
- * @return true if the fileName matches the wildcard string
- * @see IOCase#SYSTEM
- */
- public static boolean wildcardMatchOnSystem(final String fileName, final String wildcardMatcher) {
- return wildcardMatch(fileName, wildcardMatcher, IOCase.SYSTEM);
- }
-
- /**
- * Checks a fileName to see if it matches the specified wildcard matcher
* allowing control over case-sensitivity.
*
* The wildcard matcher uses the characters '?' and '*' to represent a
@@ -1356,20 +1567,18 @@
*
* @param fileName the fileName to match on
* @param wildcardMatcher the wildcard string to match against
- * @param caseSensitivity what case sensitivity rule to use, null means case-sensitive
+ * @param ioCase what case sensitivity rule to use, null means case-sensitive
* @return true if the fileName matches the wildcard string
* @since 1.3
*/
- public static boolean wildcardMatch(final String fileName, final String wildcardMatcher, IOCase caseSensitivity) {
+ public static boolean wildcardMatch(final String fileName, final String wildcardMatcher, IOCase ioCase) {
if (fileName == null && wildcardMatcher == null) {
return true;
}
if (fileName == null || wildcardMatcher == null) {
return false;
}
- if (caseSensitivity == null) {
- caseSensitivity = IOCase.SENSITIVE;
- }
+ ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
final String[] wcs = splitOnTokens(wildcardMatcher);
boolean anyChars = false;
int textIdx = 0;
@@ -1407,16 +1616,16 @@
// matching text token
if (anyChars) {
// any chars then try to locate text token
- textIdx = caseSensitivity.checkIndexOf(fileName, textIdx, wcs[wcsIdx]);
+ textIdx = ioCase.checkIndexOf(fileName, textIdx, wcs[wcsIdx]);
if (textIdx == NOT_FOUND) {
// token not found
break;
}
- final int repeat = caseSensitivity.checkIndexOf(fileName, textIdx + 1, wcs[wcsIdx]);
+ final int repeat = ioCase.checkIndexOf(fileName, textIdx + 1, wcs[wcsIdx]);
if (repeat >= 0) {
backtrack.push(new int[] {wcsIdx, repeat});
}
- } else if (!caseSensitivity.checkRegionMatches(fileName, textIdx, wcs[wcsIdx])) {
+ } else if (!ioCase.checkRegionMatches(fileName, textIdx, wcs[wcsIdx])) {
// matching from current position
// couldn't match token
break;
@@ -1441,191 +1650,34 @@
}
/**
- * Splits a string into a number of tokens.
- * The text is split by '?' and '*'.
- * Where multiple '*' occur consecutively they are collapsed into a single '*'.
+ * Checks a fileName to see if it matches the specified wildcard matcher
+ * using the case rules of the system.
+ *
+ * The wildcard matcher uses the characters '?' and '*' to represent a
+ * single or multiple (zero or more) wildcard characters.
+ * This is the same as often found on DOS/Unix command lines.
+ * The check is case-sensitive on Unix and case-insensitive on Windows.
+ *
+ * N.B. the sequence "*?" does not work properly at present in match strings.
*
- * @param text the text to split
- * @return the array of tokens, never null
+ * @param fileName the fileName to match on
+ * @param wildcardMatcher the wildcard string to match against
+ * @return true if the fileName matches the wildcard string
+ * @see IOCase#SYSTEM
*/
- static String[] splitOnTokens(final String text) {
- // used by wildcardMatch
- // package level so a unit test may run on this
-
- if (text.indexOf('?') == NOT_FOUND && text.indexOf('*') == NOT_FOUND) {
- return new String[] { text };
- }
-
- final char[] array = text.toCharArray();
- final ArrayList list = new ArrayList<>();
- final StringBuilder buffer = new StringBuilder();
- char prevChar = 0;
- for (final char ch : array) {
- if (ch == '?' || ch == '*') {
- if (buffer.length() != 0) {
- list.add(buffer.toString());
- buffer.setLength(0);
- }
- if (ch == '?') {
- list.add("?");
- } else if (prevChar != '*') {// ch == '*' here; check if previous char was '*'
- list.add("*");
- }
- } else {
- buffer.append(ch);
- }
- prevChar = ch;
- }
- if (buffer.length() != 0) {
- list.add(buffer.toString());
- }
-
- return list.toArray(EMPTY_STRING_ARRAY);
+ public static boolean wildcardMatchOnSystem(final String fileName, final String wildcardMatcher) {
+ return wildcardMatch(fileName, wildcardMatcher, IOCase.SYSTEM);
}
/**
- * Checks whether a given string is a valid host name according to
- * RFC 3986.
- *
- *
Accepted are IP addresses (v4 and v6) as well as what the
- * RFC calls a "reg-name". Percent encoded names don't seem to be
- * valid names in UNC paths.
- *
- * @see "https://tools.ietf.org/html/rfc3986#section-3.2.2"
- * @param name the hostname to validate
- * @return true if the given name is a valid host name
+ * Instances should NOT be constructed in standard programming.
*/
- private static boolean isValidHostName(final String name) {
- return isIPv6Address(name) || isRFC3986HostName(name);
+ public FilenameUtils() {
}
-
- private static final Pattern IPV4_PATTERN =
- Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$");
- private static final int IPV4_MAX_OCTET_VALUE = 255;
-
- /**
- * Checks whether a given string represents a valid IPv4 address.
- *
- * @param name the name to validate
- * @return true if the given name is a valid IPv4 address
- */
- // mostly copied from org.apache.commons.validator.routines.InetAddressValidator#isValidInet4Address
- private static boolean isIPv4Address(final String name) {
- final Matcher m = IPV4_PATTERN.matcher(name);
- if (!m.matches() || m.groupCount() != 4) {
- return false;
- }
-
- // verify that address subgroups are legal
- for (int i = 1; i <= 4; i++) {
- final String ipSegment = m.group(i);
- final int iIpSegment = Integer.parseInt(ipSegment);
- if (iIpSegment > IPV4_MAX_OCTET_VALUE) {
- return false;
- }
-
- if (ipSegment.length() > 1 && ipSegment.startsWith("0")) {
- return false;
- }
-
- }
-
- return true;
- }
-
- private static final int IPV6_MAX_HEX_GROUPS = 8;
- private static final int IPV6_MAX_HEX_DIGITS_PER_GROUP = 4;
- private static final int MAX_UNSIGNED_SHORT = 0xffff;
- private static final int BASE_16 = 16;
-
- // copied from org.apache.commons.validator.routines.InetAddressValidator#isValidInet6Address
- /**
- * Checks whether a given string represents a valid IPv6 address.
- *
- * @param inet6Address the name to validate
- * @return true if the given name is a valid IPv6 address
- */
- private static boolean isIPv6Address(final String inet6Address) {
- final boolean containsCompressedZeroes = inet6Address.contains("::");
- if (containsCompressedZeroes && (inet6Address.indexOf("::") != inet6Address.lastIndexOf("::"))) {
- return false;
- }
- if ((inet6Address.startsWith(":") && !inet6Address.startsWith("::"))
- || (inet6Address.endsWith(":") && !inet6Address.endsWith("::"))) {
- return false;
- }
- String[] octets = inet6Address.split(":");
- if (containsCompressedZeroes) {
- final List octetList = new ArrayList<>(Arrays.asList(octets));
- if (inet6Address.endsWith("::")) {
- // String.split() drops ending empty segments
- octetList.add("");
- } else if (inet6Address.startsWith("::") && !octetList.isEmpty()) {
- octetList.remove(0);
- }
- octets = octetList.toArray(EMPTY_STRING_ARRAY);
- }
- if (octets.length > IPV6_MAX_HEX_GROUPS) {
- return false;
- }
- int validOctets = 0;
- int emptyOctets = 0; // consecutive empty chunks
- for (int index = 0; index < octets.length; index++) {
- final String octet = octets[index];
- if (octet.isEmpty()) {
- emptyOctets++;
- if (emptyOctets > 1) {
- return false;
- }
- } else {
- emptyOctets = 0;
- // Is last chunk an IPv4 address?
- if (index == octets.length - 1 && octet.contains(".")) {
- if (!isIPv4Address(octet)) {
- return false;
- }
- validOctets += 2;
- continue;
- }
- if (octet.length() > IPV6_MAX_HEX_DIGITS_PER_GROUP) {
- return false;
- }
- final int octetInt;
- try {
- octetInt = Integer.parseInt(octet, BASE_16);
- } catch (final NumberFormatException e) {
- return false;
- }
- if (octetInt < 0 || octetInt > MAX_UNSIGNED_SHORT) {
- return false;
- }
- }
- validOctets++;
- }
- return validOctets <= IPV6_MAX_HEX_GROUPS && (validOctets >= IPV6_MAX_HEX_GROUPS || containsCompressedZeroes);
- }
-
- private static final Pattern REG_NAME_PART_PATTERN = Pattern.compile("^[a-zA-Z0-9][a-zA-Z0-9-]*$");
-
- /**
- * Checks whether a given string is a valid host name according to
- * RFC 3986 - not accepting IP addresses.
- *
- * @see "https://tools.ietf.org/html/rfc3986#section-3.2.2"
- * @param name the hostname to validate
- * @return true if the given name is a valid host name
- */
- private static boolean isRFC3986HostName(final String name) {
- final String[] parts = name.split("\\.", -1);
- for (int i = 0; i < parts.length; i++) {
- if (parts[i].isEmpty()) {
- // trailing dot is legal, otherwise we've hit a .. sequence
- return i == parts.length - 1;
- }
- if (!REG_NAME_PART_PATTERN.matcher(parts[i]).matches()) {
- return false;
- }
- }
- return true;
- }
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java (.../HexDump.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/HexDump.java (.../HexDump.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,27 +18,66 @@
import java.io.IOException;
import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
+import java.util.Objects;
+import org.apache.commons.io.output.CloseShieldOutputStream;
+
/**
* Dumps data in hexadecimal format.
*
* Provides a single function to take an array of bytes and display it
* in hexadecimal form.
+ *
*/
public class HexDump {
/**
- * Instances should NOT be constructed in standard programming.
+ * The line-separator (initializes to "line.separator" system property).
+ *
+ * @deprecated Use {@link System#lineSeparator()}.
*/
- public HexDump() {
+ @Deprecated
+ public static final String EOL = System.lineSeparator();
+
+ private static final char[] HEX_CODES =
+ {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+
+ private static final int[] SHIFTS =
+ {
+ 28, 24, 20, 16, 12, 8, 4, 0
+ };
+
+ /**
+ * Dumps an array of bytes to an Appendable. The output is formatted
+ * for human inspection, with a hexadecimal offset followed by the
+ * hexadecimal values of the next 16 bytes of data and the printable ASCII
+ * characters (if any) that those bytes represent printed per each line
+ * of output.
+ *
+ * @param data the byte array to be dumped
+ * @param appendable the Appendable to which the data is to be written
+ *
+ * @throws IOException is thrown if anything goes wrong writing
+ * the data to appendable
+ * @throws NullPointerException if the output appendable is null
+ *
+ * @since 2.12.0
+ */
+ public static void dump(final byte[] data, final Appendable appendable)
+ throws IOException {
+ dump(data, 0, appendable, 0, data.length);
}
/**
- * Dump an array of bytes to an OutputStream. The output is formatted
+ * Dumps an array of bytes to an Appendable. The output is formatted
* for human inspection, with a hexadecimal offset followed by the
* hexadecimal values of the next 16 bytes of data and the printable ASCII
* characters (if any) that those bytes represent printed per each line
@@ -50,42 +89,45 @@
* offset argument should be set to 2048. The offset value printed
* at the beginning of each line indicates where in that larger entity
* the first byte on that line is located.
- *
- * All bytes between the given index (inclusive) and the end of the
- * data array are dumped.
+ *
*
* @param data the byte array to be dumped
* @param offset offset of the byte array within a larger entity
- * @param stream the OutputStream to which the data is to be
- * written
+ * @param appendable the Appendable to which the data is to be written
* @param index initial index into the byte array
+ * @param length number of bytes to dump from the array
*
* @throws IOException is thrown if anything goes wrong writing
- * the data to stream
- * @throws ArrayIndexOutOfBoundsException if the index is
+ * the data to appendable
+ * @throws ArrayIndexOutOfBoundsException if the index or length is
* outside the data array's bounds
- * @throws IllegalArgumentException if the output stream is null
+ * @throws NullPointerException if the output appendable is null
+ *
+ * @since 2.12.0
*/
-
public static void dump(final byte[] data, final long offset,
- final OutputStream stream, final int index)
- throws IOException, ArrayIndexOutOfBoundsException,
- IllegalArgumentException {
-
+ final Appendable appendable, final int index,
+ final int length)
+ throws IOException, ArrayIndexOutOfBoundsException {
+ Objects.requireNonNull(appendable, "appendable");
if (index < 0 || index >= data.length) {
throw new ArrayIndexOutOfBoundsException(
"illegal index: " + index + " into array of length "
+ data.length);
}
- if (stream == null) {
- throw new IllegalArgumentException("cannot write to nullstream");
- }
long display_offset = offset + index;
final StringBuilder buffer = new StringBuilder(74);
- for (int j = index; j < data.length; j += 16) {
- int chars_read = data.length - j;
+ // TODO Use Objects.checkFromIndexSize(index, length, data.length) when upgrading to JDK9
+ if (length < 0 || index + length > data.length) {
+ throw new ArrayIndexOutOfBoundsException(String.format("Range [%s, % 16) {
chars_read = 16;
}
@@ -105,57 +147,88 @@
buffer.append('.');
}
}
- buffer.append(EOL);
- // make explicit the dependency on the default encoding
- stream.write(buffer.toString().getBytes(Charset.defaultCharset()));
- stream.flush();
+ buffer.append(System.lineSeparator());
+ appendable.append(buffer);
buffer.setLength(0);
display_offset += chars_read;
}
}
/**
- * The line-separator (initializes to "line.separator" system property.
+ * Dumps an array of bytes to an OutputStream. The output is formatted
+ * for human inspection, with a hexadecimal offset followed by the
+ * hexadecimal values of the next 16 bytes of data and the printable ASCII
+ * characters (if any) that those bytes represent printed per each line
+ * of output.
+ *
+ * The offset argument specifies the start offset of the data array
+ * within a larger entity like a file or an incoming stream. For example,
+ * if the data array contains the third kibibyte of a file, then the
+ * offset argument should be set to 2048. The offset value printed
+ * at the beginning of each line indicates where in that larger entity
+ * the first byte on that line is located.
+ *
+ *
+ * All bytes between the given index (inclusive) and the end of the
+ * data array are dumped.
+ *
+ *
+ * @param data the byte array to be dumped
+ * @param offset offset of the byte array within a larger entity
+ * @param stream the OutputStream to which the data is to be
+ * written
+ * @param index initial index into the byte array
+ *
+ * @throws IOException is thrown if anything goes wrong writing
+ * the data to stream
+ * @throws ArrayIndexOutOfBoundsException if the index is
+ * outside the data array's bounds
+ * @throws NullPointerException if the output stream is null
*/
- public static final String EOL =
- System.getProperty("line.separator");
- private static final char[] _hexcodes =
- {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'
- };
- private static final int[] _shifts =
- {
- 28, 24, 20, 16, 12, 8, 4, 0
- };
+ @SuppressWarnings("resource") // Caller closes stream
+ public static void dump(final byte[] data, final long offset,
+ final OutputStream stream, final int index)
+ throws IOException, ArrayIndexOutOfBoundsException {
+ Objects.requireNonNull(stream, "stream");
+ try (OutputStreamWriter out = new OutputStreamWriter(CloseShieldOutputStream.wrap(stream), Charset.defaultCharset())) {
+ dump(data, offset, out, index, data.length - index);
+ }
+ }
+
/**
- * Dump a long value into a StringBuilder.
+ * Dumps a byte value into a StringBuilder.
*
+ * @param _cbuffer the StringBuilder to dump the value in
+ * @param value the byte value to be dumped
+ * @return StringBuilder containing the dumped value.
+ */
+ private static StringBuilder dump(final StringBuilder _cbuffer, final byte value) {
+ for (int j = 0; j < 2; j++) {
+ _cbuffer.append(HEX_CODES[value >> SHIFTS[j + 6] & 15]);
+ }
+ return _cbuffer;
+ }
+
+ /**
+ * Dumps a long value into a StringBuilder.
+ *
* @param _lbuffer the StringBuilder to dump the value in
* @param value the long value to be dumped
* @return StringBuilder containing the dumped value.
*/
private static StringBuilder dump(final StringBuilder _lbuffer, final long value) {
for (int j = 0; j < 8; j++) {
_lbuffer
- .append(_hexcodes[(int) (value >> _shifts[j]) & 15]);
+ .append(HEX_CODES[(int) (value >> SHIFTS[j]) & 15]);
}
return _lbuffer;
}
/**
- * Dump a byte value into a StringBuilder.
- *
- * @param _cbuffer the StringBuilder to dump the value in
- * @param value the byte value to be dumped
- * @return StringBuilder containing the dumped value.
+ * Instances should NOT be constructed in standard programming.
*/
- private static StringBuilder dump(final StringBuilder _cbuffer, final byte value) {
- for (int j = 0; j < 2; j++) {
- _cbuffer.append(_hexcodes[value >> _shifts[j + 6] & 15]);
- }
- return _cbuffer;
+ public HexDump() {
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/IO.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/IO.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/IO.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+/**
+ * Component-wide operations on Apache Commons IO.
+ */
+final class IO {
+
+ /**
+ * Clears any state, throughout Apache Commons IO. Handy for tests.
+ */
+ static void clear() {
+ IOUtils.clear();
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java (.../IOCase.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/IOCase.java (.../IOCase.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -17,6 +17,7 @@
package org.apache.commons.io;
import java.util.Objects;
+import java.util.stream.Stream;
/**
* Enumeration of IO case sensitivity.
@@ -39,12 +40,12 @@
public enum IOCase {
/**
- * The constant for case sensitive regardless of operating system.
+ * The constant for case-sensitive regardless of operating system.
*/
SENSITIVE("Sensitive", true),
/**
- * The constant for case insensitive regardless of operating system.
+ * The constant for case-insensitive regardless of operating system.
*/
INSENSITIVE("Insensitive", false),
@@ -53,7 +54,7 @@
* Windows is case-insensitive when comparing file names, Unix is case-sensitive.
*
* Note: This only caters for Windows and Unix. Other operating
- * systems (e.g. OSX and OpenVMS) are treated as case sensitive if they use the
+ * systems (e.g. OSX and OpenVMS) are treated as case-sensitive if they use the
* Unix file separator and case-insensitive if they use the Windows file separator
* (see {@link java.io.File#separatorChar}).
*
@@ -62,28 +63,11 @@
* versa, then the value of the case-sensitivity flag will change.
*
*/
- SYSTEM("System", !FilenameUtils.isSystemWindows());
+ SYSTEM("System", FileSystem.getCurrent().isCaseSensitive());
- /**
- * Tests for cases sensitivity in a null-safe manner.
- *
- * @param caseSensitivity an IOCase.
- * @return true if the input is non-null and {@link #isCaseSensitive()}.
- * @since 2.10.0
- */
- public static boolean isCaseSensitive(final IOCase caseSensitivity) {
- return caseSensitivity != null && !caseSensitivity.isCaseSensitive();
- }
-
/** Serialization version. */
private static final long serialVersionUID = -6343169151696340687L;
- /** The enumeration name. */
- private final String name;
-
- /** The sensitivity flag. */
- private final transient boolean sensitive;
-
/**
* Factory method to create an IOCase from a name.
*
@@ -92,51 +76,48 @@
* @throws IllegalArgumentException if the name is invalid
*/
public static IOCase forName(final String name) {
- for (final IOCase ioCase : IOCase.values()) {
- if (ioCase.getName().equals(name)) {
- return ioCase;
- }
- }
- throw new IllegalArgumentException("Invalid IOCase name: " + name);
+ return Stream.of(IOCase.values()).filter(ioCase -> ioCase.getName().equals(name)).findFirst()
+ .orElseThrow(() -> new IllegalArgumentException("Illegal IOCase name: " + name));
}
/**
- * Constructs a new instance.
+ * Tests for cases sensitivity in a null-safe manner.
*
- * @param name the name
- * @param sensitive the sensitivity
+ * @param ioCase an IOCase.
+ * @return true if the input is non-null and {@link #isCaseSensitive()}.
+ * @since 2.10.0
*/
- IOCase(final String name, final boolean sensitive) {
- this.name = name;
- this.sensitive = sensitive;
+ public static boolean isCaseSensitive(final IOCase ioCase) {
+ return ioCase != null && ioCase.isCaseSensitive();
}
/**
- * Replaces the enumeration from the stream with a real one.
- * This ensures that the correct flag is set for SYSTEM.
+ * Returns the given value if not-null, the defaultValue if null.
*
- * @return the resolved object
+ * @param value the value to test.
+ * @param defaultValue the default value.
+ * @return the given value if not-null, the defaultValue if null.
+ * @since 2.12.0
*/
- private Object readResolve() {
- return forName(name);
+ public static IOCase value(final IOCase value, final IOCase defaultValue) {
+ return value != null ? value : defaultValue;
}
- /**
- * Gets the name of the constant.
- *
- * @return the name of the constant
- */
- public String getName() {
- return name;
- }
+ /** The enumeration name. */
+ private final String name;
+ /** The sensitivity flag. */
+ private final transient boolean sensitive;
+
/**
- * Does the object represent case sensitive comparison.
+ * Constructs a new instance.
*
- * @return true if case sensitive
+ * @param name the name
+ * @param sensitive the sensitivity
*/
- public boolean isCaseSensitive() {
- return sensitive;
+ IOCase(final String name, final boolean sensitive) {
+ this.name = name;
+ this.sensitive = sensitive;
}
/**
@@ -158,39 +139,6 @@
}
/**
- * Compares two strings using the case-sensitivity rule.
- *
- * This method mimics {@link String#equals} but takes case-sensitivity
- * into account.
- *
- *
- * @param str1 the first string to compare, not null
- * @param str2 the second string to compare, not null
- * @return true if equal using the case rules
- * @throws NullPointerException if either string is null
- */
- public boolean checkEquals(final String str1, final String str2) {
- Objects.requireNonNull(str1, "str1");
- Objects.requireNonNull(str2, "str2");
- return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
- }
-
- /**
- * Checks if one string starts with another using the case-sensitivity rule.
- *
- * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
- * into account.
- *
- *
- * @param str the string to check
- * @param start the start to compare against
- * @return true if equal using the case rules, false if either input is null
- */
- public boolean checkStartsWith(final String str, final String start) {
- return str != null && start != null && str.regionMatches(!sensitive, 0, start, 0, start.length());
- }
-
- /**
* Checks if one string ends with another using the case-sensitivity rule.
*
* This method mimics {@link String#endsWith} but takes case-sensitivity
@@ -210,6 +158,24 @@
}
/**
+ * Compares two strings using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#equals} but takes case-sensitivity
+ * into account.
+ *
+ *
+ * @param str1 the first string to compare, not null
+ * @param str2 the second string to compare, not null
+ * @return true if equal using the case rules
+ * @throws NullPointerException if either string is null
+ */
+ public boolean checkEquals(final String str1, final String str2) {
+ Objects.requireNonNull(str1, "str1");
+ Objects.requireNonNull(str2, "str2");
+ return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
+ }
+
+ /**
* Checks if one string contains another starting at a specific index using the
* case-sensitivity rule.
*
@@ -255,6 +221,49 @@
}
/**
+ * Checks if one string starts with another using the case-sensitivity rule.
+ *
+ * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
+ * into account.
+ *
+ *
+ * @param str the string to check
+ * @param start the start to compare against
+ * @return true if equal using the case rules, false if either input is null
+ */
+ public boolean checkStartsWith(final String str, final String start) {
+ return str != null && start != null && str.regionMatches(!sensitive, 0, start, 0, start.length());
+ }
+
+ /**
+ * Gets the name of the constant.
+ *
+ * @return the name of the constant
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Does the object represent case-sensitive comparison.
+ *
+ * @return true if case-sensitive
+ */
+ public boolean isCaseSensitive() {
+ return sensitive;
+ }
+
+ /**
+ * Replaces the enumeration from the stream with a real one.
+ * This ensures that the correct flag is set for SYSTEM.
+ *
+ * @return the resolved object
+ */
+ private Object readResolve() {
+ return forName(name);
+ }
+
+ /**
* Gets a string describing the sensitivity.
*
* @return a string describing the sensitivity
Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionList.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionList.java (.../IOExceptionList.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/IOExceptionList.java (.../IOExceptionList.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,41 +18,71 @@
package org.apache.commons.io;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
/**
- * A IOException based on a list of Throwable causes.
+ * An IOException based on a list of Throwable causes.
*
* The first exception in the list is used as this exception's cause and is accessible with the usual
* {@link #getCause()} while the complete list is accessible with {@link #getCauseList()}.
*
*
* @since 2.7
*/
-public class IOExceptionList extends IOException {
+public class IOExceptionList extends IOException implements Iterable {
private static final long serialVersionUID = 1L;
+
+ /**
+ * Throws this exception if the list is not null or empty.
+ *
+ * @param causeList The list to test.
+ * @param message The detail message, see {@link #getMessage()}.
+ * @throws IOExceptionList if the list is not null or empty.
+ * @since 2.12.0
+ */
+ public static void checkEmpty(final List extends Throwable> causeList, final Object message) throws IOExceptionList {
+ if (!isEmpty(causeList)) {
+ throw new IOExceptionList(Objects.toString(message, null), causeList);
+ }
+ }
+
+ private static boolean isEmpty(final List extends Throwable> causeList) {
+ return size(causeList) == 0;
+ }
+
+ private static int size(final List extends Throwable> causeList) {
+ return causeList != null ? causeList.size() : 0;
+ }
+
+ private static String toMessage(final List extends Throwable> causeList) {
+ return String.format("%,d exception(s): %s", size(causeList), causeList);
+ }
+
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.
*/
public IOExceptionList(final List extends Throwable> causeList) {
- this(String.format("%,d exceptions: %s", causeList == null ? 0 : causeList.size(), causeList), causeList);
+ this(toMessage(causeList), causeList);
}
/**
- * 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.
* @since 2.9.0
*/
public IOExceptionList(final String message, final List extends Throwable> causeList) {
- super(message, causeList == null || causeList.isEmpty() ? null : causeList.get(0));
+ super(message != null ? message : toMessage(causeList), isEmpty(causeList) ? null : causeList.get(0));
this.causeList = causeList == null ? Collections.emptyList() : causeList;
}
@@ -76,7 +106,7 @@
* @return The list of causes.
*/
public T getCause(final int index, final Class clazz) {
- return clazz.cast(causeList.get(index));
+ return clazz.cast(getCause(index));
}
/**
@@ -86,7 +116,7 @@
* @return The list of causes.
*/
public List getCauseList() {
- return (List) causeList;
+ return (List) new ArrayList<>(causeList);
}
/**
@@ -97,7 +127,12 @@
* @return The list of causes.
*/
public List getCauseList(final Class clazz) {
- return (List) causeList;
+ return (List) new ArrayList<>(causeList);
}
+ @Override
+ public Iterator iterator() {
+ return getCauseList().iterator();
+ }
+
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOIndexedException.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/IOIndexedException.java (.../IOIndexedException.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/IOIndexedException.java (.../IOIndexedException.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -27,20 +27,7 @@
public class IOIndexedException extends IOException {
private static final long serialVersionUID = 1L;
- private final int index;
-
/**
- * Creates a new exception.
- *
- * @param index index of this exception.
- * @param cause cause exceptions.
- */
- public IOIndexedException(final int index, final Throwable cause) {
- super(toMessage(index, cause), cause);
- this.index = index;
- }
-
- /**
* Converts input to a suitable String for exception message.
*
* @param index An index into a source collection.
@@ -56,6 +43,22 @@
}
/**
+ * Index.
+ */
+ private final int index;
+
+ /**
+ * Constructs a new exception.
+ *
+ * @param index index of this exception.
+ * @param cause cause exceptions.
+ */
+ public IOIndexedException(final int index, final Throwable cause) {
+ super(toMessage(index, cause), cause);
+ this.index = index;
+ }
+
+ /**
* The index of this exception.
*
* @return index of this exception.
Index: 3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java (.../IOUtils.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/IOUtils.java (.../IOUtils.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -31,6 +31,7 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
+import java.io.UncheckedIOException;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.ServerSocket;
@@ -40,20 +41,31 @@
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
+import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+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;
+import org.apache.commons.io.function.IOTriFunction;
+import org.apache.commons.io.input.QueueInputStream;
import org.apache.commons.io.output.AppendableWriter;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.io.output.NullOutputStream;
+import org.apache.commons.io.output.NullWriter;
import org.apache.commons.io.output.StringBuilderWriter;
import org.apache.commons.io.output.ThresholdingOutputStream;
import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
@@ -62,8 +74,9 @@
* General IO stream manipulation utilities.
*
* This class provides static utility methods for input/output operations.
+ *
*
- *
[Deprecated] closeQuietly - these methods close a stream ignoring nulls and exceptions
+ *
closeQuietly - these methods close a stream ignoring nulls and exceptions
*
toXxx/read - these methods read data from a stream
*
write - these methods write data to a stream
*
copy - these methods copy all the data from one stream to another
@@ -76,13 +89,16 @@
* encouraged to always specify an encoding because relying on the platform
* default can lead to unexpected results, for example when moving from
* development to production.
+ *
*
* All the methods in this class that read a stream are buffered internally.
- * This means that there is no cause to use a {@code BufferedInputStream}
- * or {@code BufferedReader}. The default buffer size of 4K has been shown
+ * This means that there is no cause to use a {@link BufferedInputStream}
+ * or {@link BufferedReader}. The default buffer size of 4K has been shown
* to be efficient in tests.
+ *
*
* The various copy methods all delegate the actual copying to one of the following methods:
+ *
* Applications can re-use buffers by using the underlying methods directly.
* This may improve performance for applications that need to do a lot of copying.
+ *
*
* Wherever possible, the methods in this class do not flush or close
* the stream. This is to avoid making non-portable assumptions about the
* streams' origin and further use. Thus the caller is still responsible for
* closing streams after use.
+ *
*/
public class IOUtils {
// NOTE: This class is focused on InputStream, OutputStream, Reader and
@@ -178,16 +197,26 @@
public static final String LINE_SEPARATOR_WINDOWS = StandardLineSeparator.CRLF.getString();
/**
- * Internal byte array buffer.
+ * Internal byte array buffer, intended for both reading and writing.
*/
- private static final ThreadLocal SKIP_BYTE_BUFFER = ThreadLocal.withInitial(IOUtils::byteArray);
+ private static final ThreadLocal SCRATCH_BYTE_BUFFER_RW = ThreadLocal.withInitial(IOUtils::byteArray);
/**
- * Internal byte array buffer.
+ * Internal byte array buffer, intended for write only operations.
*/
- private static final ThreadLocal SKIP_CHAR_BUFFER = ThreadLocal.withInitial(IOUtils::charArray);
+ private static final byte[] SCRATCH_BYTE_BUFFER_WO = byteArray();
/**
+ * Internal char array buffer, intended for both reading and writing.
+ */
+ private static final ThreadLocal SCRATCH_CHAR_BUFFER_RW = ThreadLocal.withInitial(IOUtils::charArray);
+
+ /**
+ * Internal char array buffer, intended for write only operations.
+ */
+ private static final char[] SCRATCH_CHAR_BUFFER_WO = charArray();
+
+ /**
* Returns the given InputStream if it is already a {@link BufferedInputStream}, otherwise creates a
* BufferedInputStream from the given InputStream.
*
@@ -332,6 +361,7 @@
*
* @param size array size.
* @return a new byte array of the given size.
+ * @throws NegativeArraySizeException if the size is negative.
* @since 2.9.0
*/
public static byte[] byteArray(final int size) {
@@ -362,6 +392,21 @@
}
/**
+ * Clears any state.
+ *
+ *
Removes the current thread's value for thread-local variables.
+ *
Sets static scratch arrays to 0s.
+ *
+ * @see IO#clear()
+ */
+ static void clear() {
+ SCRATCH_BYTE_BUFFER_RW.remove();
+ SCRATCH_CHAR_BUFFER_RW.remove();
+ Arrays.fill(SCRATCH_BYTE_BUFFER_WO, (byte) 0);
+ Arrays.fill(SCRATCH_CHAR_BUFFER_WO, (char) 0);
+ }
+
+ /**
* Closes the given {@link Closeable} as a null-safe operation.
*
* @param closeable The resource to close, may be null.
@@ -375,18 +420,14 @@
}
/**
- * Closes the given {@link Closeable} as a null-safe operation.
+ * Closes the given {@link Closeable}s as null-safe operations.
*
* @param closeables The resource(s) to close, may be null.
- * @throws IOException if an I/O error occurs.
+ * @throws IOExceptionList if an I/O error occurs.
* @since 2.8.0
*/
- public static void close(final Closeable... closeables) throws IOException {
- if (closeables != null) {
- for (final Closeable closeable : closeables) {
- close(closeable);
- }
- }
+ public static void close(final Closeable... closeables) throws IOExceptionList {
+ IOConsumer.forAll(IOUtils::close, closeables);
}
/**
@@ -422,8 +463,17 @@
}
/**
- * Closes a {@code Closeable} unconditionally.
+ * Avoids the need to type cast.
*
+ * @param closeable the object to close, may be null
+ */
+ private static void closeQ(final Closeable closeable) {
+ closeQuietly(closeable, null);
+ }
+
+ /**
+ * Closes a {@link Closeable} unconditionally.
+ *
*
* Equivalent to {@link Closeable#close()}, except any exceptions will be ignored. This is typically used in
* finally blocks.
@@ -460,14 +510,14 @@
* @param closeable the objects to close, may be null or already closed
* @since 2.0
*
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Closeable closeable) {
- closeQuietly(closeable, (Consumer) null);
+ closeQuietly(closeable, null);
}
/**
- * Closes a {@code Closeable} unconditionally.
+ * Closes a {@link Closeable} unconditionally.
*
* Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
*
@@ -510,15 +560,12 @@
* @param closeables the objects to close, may be null or already closed
* @see #closeQuietly(Closeable)
* @since 2.5
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Closeable... closeables) {
- if (closeables == null) {
- return;
+ if (closeables != null) {
+ closeQuietly(Arrays.stream(closeables));
}
- for (final Closeable closeable : closeables) {
- closeQuietly(closeable);
- }
}
/**
@@ -541,12 +588,14 @@
}
/**
- * Closes an {@code InputStream} unconditionally.
+ * Closes an {@link InputStream} unconditionally.
*
* Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* byte[] data = new byte[1024];
* InputStream in = null;
@@ -565,19 +614,37 @@
*
*
* @param input the InputStream to close, may be null or already closed
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final InputStream input) {
- closeQuietly((Closeable) input);
+ closeQ(input);
}
/**
- * Closes an {@code OutputStream} unconditionally.
+ * Closes an iterable of {@link Closeable} unconditionally.
*
+ * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored.
+ *
+ *
+ * @param closeables the objects to close, may be null or already closed
+ * @see #closeQuietly(Closeable)
+ * @since 2.12.0
+ */
+ public static void closeQuietly(final Iterable closeables) {
+ if (closeables != null) {
+ closeables.forEach(IOUtils::closeQuietly);
+ }
+ }
+
+ /**
+ * Closes an {@link OutputStream} unconditionally.
+ *
* Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* @param output the OutputStream to close, may be null or already closed
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final OutputStream output) {
- closeQuietly((Closeable) output);
+ closeQ(output);
}
/**
- * Closes an {@code Reader} unconditionally.
+ * Closes an {@link Reader} unconditionally.
*
* Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* char[] data = new char[1024];
* Reader in = null;
@@ -628,19 +697,21 @@
*
*
* @param reader the Reader to close, may be null or already closed
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Reader reader) {
- closeQuietly((Closeable) reader);
+ closeQ(reader);
}
/**
- * Closes a {@code Selector} unconditionally.
+ * Closes a {@link Selector} unconditionally.
*
* Equivalent to {@link Selector#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* Selector selector = null;
* try {
@@ -659,19 +730,21 @@
*
* @param selector the Selector to close, may be null or already closed
* @since 2.2
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Selector selector) {
- closeQuietly((Closeable) selector);
+ closeQ(selector);
}
/**
- * Closes a {@code ServerSocket} unconditionally.
+ * Closes a {@link ServerSocket} unconditionally.
*
* Equivalent to {@link ServerSocket#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* ServerSocket socket = null;
* try {
@@ -690,19 +763,21 @@
*
* @param serverSocket the ServerSocket to close, may be null or already closed
* @since 2.2
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final ServerSocket serverSocket) {
- closeQuietly((Closeable) serverSocket);
+ closeQ(serverSocket);
}
/**
- * Closes a {@code Socket} unconditionally.
+ * Closes a {@link Socket} unconditionally.
*
* Equivalent to {@link Socket#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* Socket socket = null;
* try {
@@ -721,19 +796,37 @@
*
* @param socket the Socket to close, may be null or already closed
* @since 2.0
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Socket socket) {
- closeQuietly((Closeable) socket);
+ closeQ(socket);
}
/**
- * Closes an {@code Writer} unconditionally.
+ * Closes a stream of {@link Closeable} unconditionally.
*
+ * Equivalent calling {@link Closeable#close()} on each element, except any exceptions will be ignored.
+ *
+ *
+ * @param closeables the objects to close, may be null or already closed
+ * @see #closeQuietly(Closeable)
+ * @since 2.12.0
+ */
+ public static void closeQuietly(final Stream closeables) {
+ if (closeables != null) {
+ closeables.forEach(IOUtils::closeQuietly);
+ }
+ }
+
+ /**
+ * Closes an {@link Writer} unconditionally.
+ *
* Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
* This is typically used in finally blocks.
+ *
*
* Example code:
+ *
*
* Writer out = null;
* try {
@@ -751,43 +844,56 @@
*
*
* @param writer the Writer to close, may be null or already closed
- * @see Throwable#addSuppressed(java.lang.Throwable)
+ * @see Throwable#addSuppressed(Throwable)
*/
public static void closeQuietly(final Writer writer) {
- closeQuietly((Closeable) writer);
+ closeQ(writer);
}
/**
- * Consumes bytes from a {@code InputStream} and ignores them.
+ * Consumes bytes from a {@link InputStream} and ignores them.
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
*
- * @param input the {@code InputStream} to read.
+ * @param input the {@link InputStream} to read.
* @return the number of bytes copied. or {@code 0} if {@code input is null}.
* @throws NullPointerException if the InputStream is {@code null}.
- * @throws NullPointerException if the OutputStream is {@code null}.
* @throws IOException if an I/O error occurs.
* @since 2.8.0
*/
- public static long consume(final InputStream input)
- throws IOException {
- return copyLarge(input, NullOutputStream.NULL_OUTPUT_STREAM, getByteArray());
+ public static long consume(final InputStream input) throws IOException {
+ return copyLarge(input, NullOutputStream.INSTANCE);
}
/**
+ * Consumes characters from a {@link Reader} and ignores them.
+ *
+ * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+ *
+ *
+ * @param input the {@link Reader} to read.
+ * @return the number of bytes copied. or {@code 0} if {@code input is null}.
+ * @throws NullPointerException if the Reader is {@code null}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static long consume(final Reader input) throws IOException {
+ return copyLarge(input, NullWriter.INSTANCE);
+ }
+
+ /**
* Compares the contents of two Streams to determine if they are equal or
* not.
*
* This method buffers the input internally using
- * {@code BufferedInputStream} if they are not already buffered.
+ * {@link BufferedInputStream} if they are not already buffered.
*
*
* @param input1 the first stream
* @param input2 the second stream
* @return true if the content of the streams are equal or they both don't
* exist, false otherwise
- * @throws NullPointerException if either input is null
* @throws IOException if an I/O error occurs
*/
public static boolean contentEquals(final InputStream input1, final InputStream input2) throws IOException {
@@ -801,7 +907,7 @@
}
// reuse one
- final byte[] array1 = getByteArray();
+ final byte[] array1 = getScratchByteArray();
// allocate another
final byte[] array2 = byteArray();
int pos1;
@@ -837,10 +943,23 @@
}
}
+ // TODO Consider making public
+ private static boolean contentEquals(final Iterator> iterator1, final Iterator> iterator2) {
+ while (iterator1.hasNext()) {
+ if (!iterator2.hasNext()) {
+ return false;
+ }
+ if (!Objects.equals(iterator1.next(), iterator2.next())) {
+ return false;
+ }
+ }
+ return !iterator2.hasNext();
+ }
+
/**
* Compares the contents of two Readers to determine if they are equal or not.
*
- * This method buffers the input internally using {@code BufferedReader} if they are not already buffered.
+ * This method buffers the input internally using {@link BufferedReader} if they are not already buffered.
*
*
* @param input1 the first reader
@@ -859,7 +978,7 @@
}
// reuse one
- final char[] array1 = getCharArray();
+ final char[] array1 = getScratchCharArray();
// but allocate another
final char[] array2 = charArray();
int pos1;
@@ -895,54 +1014,67 @@
}
}
+ // TODO Consider making public
+ private static boolean contentEquals(final Stream> stream1, final Stream> stream2) {
+ if (stream1 == stream2) {
+ return true;
+ }
+ if (stream1 == null || stream2 == null) {
+ return false;
+ }
+ return contentEquals(stream1.iterator(), stream2.iterator());
+ }
+
+ // TODO Consider making public
+ private static boolean contentEqualsIgnoreEOL(final BufferedReader reader1, final BufferedReader reader2) {
+ if (reader1 == reader2) {
+ return true;
+ }
+ if (reader1 == null || reader2 == null) {
+ return false;
+ }
+ return contentEquals(reader1.lines(), reader2.lines());
+ }
+
/**
* Compares the contents of two Readers to determine if they are equal or
* not, ignoring EOL characters.
*
* This method buffers the input internally using
- * {@code BufferedReader} if they are not already buffered.
+ * {@link BufferedReader} if they are not already buffered.
+ *
*
* @param reader1 the first reader
* @param reader2 the second reader
* @return true if the content of the readers are equal (ignoring EOL differences), false otherwise
* @throws NullPointerException if either input is null
- * @throws IOException if an I/O error occurs
+ * @throws UncheckedIOException if an I/O error occurs
* @since 2.2
*/
@SuppressWarnings("resource")
- public static boolean contentEqualsIgnoreEOL(final Reader reader1, final Reader reader2)
- throws IOException {
+ public static boolean contentEqualsIgnoreEOL(final Reader reader1, final Reader reader2) throws UncheckedIOException {
if (reader1 == reader2) {
return true;
}
- if (reader1 == null ^ reader2 == null) {
+ if (reader1 == null || reader2 == null) {
return false;
}
- final BufferedReader br1 = toBufferedReader(reader1);
- final BufferedReader br2 = toBufferedReader(reader2);
-
- String line1 = br1.readLine();
- String line2 = br2.readLine();
- while (line1 != null && line1.equals(line2)) {
- line1 = br1.readLine();
- line2 = br2.readLine();
- }
- return Objects.equals(line1, line2);
+ return contentEqualsIgnoreEOL(toBufferedReader(reader1), toBufferedReader(reader2));
}
/**
- * Copies bytes from an {@code InputStream} to an {@code OutputStream}.
+ * Copies bytes from an {@link InputStream} to an {@link OutputStream}.
*
- * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}.
+ * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
* Large streams (over 2GB) will return a bytes copied value of {@code -1} after the copy has completed since
* the correct number of bytes cannot be returned as an int. For large streams use the
- * {@code copyLarge(InputStream, OutputStream)} method.
+ * {@link #copyLarge(InputStream, OutputStream)} method.
*
*
- * @param inputStream the {@code InputStream} to read.
- * @param outputStream the {@code OutputStream} to write.
+ * @param inputStream the {@link InputStream} to read.
+ * @param outputStream the {@link OutputStream} to write.
* @return the number of bytes copied, or -1 if greater than {@link Integer#MAX_VALUE}.
* @throws NullPointerException if the InputStream is {@code null}.
* @throws NullPointerException if the OutputStream is {@code null}.
@@ -951,21 +1083,18 @@
*/
public static int copy(final InputStream inputStream, final OutputStream outputStream) throws IOException {
final long count = copyLarge(inputStream, outputStream);
- if (count > Integer.MAX_VALUE) {
- return EOF;
- }
- return (int) count;
+ return count > Integer.MAX_VALUE ? EOF : (int) count;
}
/**
- * Copies bytes from an {@code InputStream} to an {@code OutputStream} using an internal buffer of the
+ * Copies bytes from an {@link InputStream} to an {@link OutputStream} using an internal buffer of the
* given size.
*
- * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}.
+ * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
- * @param inputStream the {@code InputStream} to read.
- * @param outputStream the {@code OutputStream} to write to
+ * @param inputStream the {@link InputStream} to read.
+ * @param outputStream the {@link OutputStream} to write to
* @param bufferSize the bufferSize used to copy from the input to the output
* @return the number of bytes copied.
* @throws NullPointerException if the InputStream is {@code null}.
@@ -979,16 +1108,18 @@
}
/**
- * Copies bytes from an {@code InputStream} to chars on a
- * {@code Writer} using the default character encoding of the platform.
+ * Copies bytes from an {@link InputStream} to chars on a
+ * {@link Writer} using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
* This method uses {@link InputStreamReader}.
+ *
*
- * @param input the {@code InputStream} to read from
- * @param writer the {@code Writer} to write to
+ * @param input the {@link InputStream} to read
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -1001,16 +1132,18 @@
}
/**
- * Copies bytes from an {@code InputStream} to chars on a
- * {@code Writer} using the specified character encoding.
+ * Copies bytes from an {@link InputStream} to chars on a
+ * {@link Writer} using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
* This method uses {@link InputStreamReader}.
+ *
*
- * @param input the {@code InputStream} to read from
- * @param writer the {@code Writer} to write to
+ * @param input the {@link InputStream} to read
+ * @param writer the {@link Writer} to write to
* @param inputCharset the charset to use for the input stream, null means platform default
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1023,19 +1156,22 @@
}
/**
- * Copies bytes from an {@code InputStream} to chars on a
- * {@code Writer} using the specified character encoding.
+ * Copies bytes from an {@link InputStream} to chars on a
+ * {@link Writer} using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link InputStreamReader}.
+ *
*
- * @param input the {@code InputStream} to read from
- * @param writer the {@code Writer} to write to
+ * @param input the {@link InputStream} to read
+ * @param writer the {@link Writer} to write to
* @param inputCharsetName the name of the requested charset for the InputStream, null means platform default
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1050,18 +1186,51 @@
}
/**
- * Copies chars from a {@code Reader} to a {@code Appendable}.
+ * Copies bytes from a {@link java.io.ByteArrayOutputStream} to a {@link QueueInputStream}.
*
+ * Unlike using JDK {@link java.io.PipedInputStream} and {@link java.io.PipedOutputStream} for this, this
+ * solution works safely in a single thread environment.
+ *
+ *
+ * @param outputStream the {@link java.io.ByteArrayOutputStream} to read.
+ * @return the {@link QueueInputStream} filled with the content of the outputStream.
+ * @throws NullPointerException if the {@link java.io.ByteArrayOutputStream} is {@code null}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12
+ */
+ @SuppressWarnings("resource") // streams are closed by the caller.
+ public static QueueInputStream copy(final java.io.ByteArrayOutputStream outputStream) throws IOException {
+ Objects.requireNonNull(outputStream, "outputStream");
+ final QueueInputStream in = new QueueInputStream();
+ outputStream.writeTo(in.newQueueOutputStream());
+ return in;
+ }
+
+ /**
+ * Copies chars from a {@link Reader} to a {@link Appendable}.
+ *
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* Large streams (over 2GB) will return a chars copied value of
* {@code -1} after the copy has completed since the correct
* number of chars cannot be returned as an int. For large streams
- * use the {@code copyLarge(Reader, Writer)} method.
+ * use the {@link #copyLarge(Reader, Writer)} method.
+ *
*
- * @param reader the {@code Reader} to read from
- * @param output the {@code Appendable} to write to
+ * @param reader the {@link Reader} to read
+ * @param output the {@link Appendable} to write to
* @return the number of characters copied, or -1 if > Integer.MAX_VALUE
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1072,14 +1241,14 @@
}
/**
- * Copies chars from a {@code Reader} to an {@code Appendable}.
+ * Copies chars from a {@link Reader} to an {@link Appendable}.
*
* This method uses the provided buffer, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
*
*
- * @param reader the {@code Reader} to read from
- * @param output the {@code Appendable} to write to
+ * @param reader the {@link Reader} to read
+ * @param output the {@link Appendable} to write to
* @param buffer the buffer to be used for the copy
* @return the number of characters copied
* @throws NullPointerException if the input or output is null
@@ -1098,20 +1267,23 @@
}
/**
- * Copies chars from a {@code Reader} to bytes on an
- * {@code OutputStream} using the default character encoding of the
+ * Copies chars from a {@link Reader} to bytes on an
+ * {@link OutputStream} using the default character encoding of the
* platform, and calling flush.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* Due to the implementation of OutputStreamWriter, this method performs a
* flush.
+ *
*
* This method uses {@link OutputStreamWriter}.
+ *
*
- * @param reader the {@code Reader} to read from
- * @param output the {@code OutputStream} to write to
+ * @param reader the {@link Reader} to read
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -1124,12 +1296,12 @@
}
/**
- * Copies chars from a {@code Reader} to bytes on an
- * {@code OutputStream} using the specified character encoding, and
+ * Copies chars from a {@link Reader} to bytes on an
+ * {@link OutputStream} using the specified character encoding, and
* calling flush.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
*
*
* Due to the implementation of OutputStreamWriter, this method performs a
@@ -1139,8 +1311,8 @@
* This method uses {@link OutputStreamWriter}.
*
*
- * @param reader the {@code Reader} to read from
- * @param output the {@code OutputStream} to write to
+ * @param reader the {@link Reader} to read
+ * @param output the {@link OutputStream} to write to
* @param outputCharset the charset to use for the OutputStream, null means platform default
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1156,23 +1328,27 @@
}
/**
- * Copies chars from a {@code Reader} to bytes on an
- * {@code OutputStream} using the specified character encoding, and
+ * Copies chars from a {@link Reader} to bytes on an
+ * {@link OutputStream} using the specified character encoding, and
* calling flush.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* Character encoding names can be found at
* IANA.
+ *
*
* Due to the implementation of OutputStreamWriter, this method performs a
* flush.
+ *
*
* This method uses {@link OutputStreamWriter}.
+ *
*
- * @param reader the {@code Reader} to read from
- * @param output the {@code OutputStream} to write to
+ * @param reader the {@link Reader} to read
+ * @param output the {@link OutputStream} to write to
* @param outputCharsetName the name of the requested charset for the OutputStream, null means platform default
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1187,18 +1363,20 @@
}
/**
- * Copies chars from a {@code Reader} to a {@code Writer}.
+ * Copies chars from a {@link Reader} to a {@link Writer}.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* Large streams (over 2GB) will return a chars copied value of
* {@code -1} after the copy has completed since the correct
* number of chars cannot be returned as an int. For large streams
- * use the {@code copyLarge(Reader, Writer)} method.
+ * use the {@link #copyLarge(Reader, Writer)} method.
+ *
*
- * @param reader the {@code Reader} to read.
- * @param writer the {@code Writer} to write.
+ * @param reader the {@link Reader} to read.
+ * @param writer the {@link Writer} to write.
* @return the number of characters copied, or -1 if > Integer.MAX_VALUE
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
@@ -1213,16 +1391,16 @@
}
/**
- * Copies bytes from a {@code URL} to an {@code OutputStream}.
+ * Copies bytes from a {@link URL} to an {@link OutputStream}.
*
- * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}.
+ * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
*
- * @param url the {@code URL} to read.
- * @param file the {@code OutputStream} to write.
+ * @param url the {@link URL} to read.
+ * @param file the {@link OutputStream} to write.
* @return the number of bytes copied.
* @throws NullPointerException if the URL is {@code null}.
* @throws NullPointerException if the OutputStream is {@code null}.
@@ -1236,16 +1414,16 @@
}
/**
- * Copies bytes from a {@code URL} to an {@code OutputStream}.
+ * Copies bytes from a {@link URL} to an {@link OutputStream}.
*
- * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}.
+ * This method buffers the input internally, so there is no need to use a {@link BufferedInputStream}.
*
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
*
- * @param url the {@code URL} to read.
- * @param outputStream the {@code OutputStream} to write.
+ * @param url the {@link URL} to read.
+ * @param outputStream the {@link OutputStream} to write.
* @return the number of bytes copied.
* @throws NullPointerException if the URL is {@code null}.
* @throws NullPointerException if the OutputStream is {@code null}.
@@ -1259,18 +1437,18 @@
}
/**
- * Copies bytes from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}.
+ * Copies bytes from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
*
- * @param inputStream the {@code InputStream} to read.
- * @param outputStream the {@code OutputStream} to write.
+ * @param inputStream the {@link InputStream} to read.
+ * @param outputStream the {@link OutputStream} to write.
* @return the number of bytes copied.
* @throws NullPointerException if the InputStream is {@code null}.
* @throws NullPointerException if the OutputStream is {@code null}.
@@ -1283,15 +1461,15 @@
}
/**
- * Copies bytes from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}.
+ * Copies bytes from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}.
*
* This method uses the provided buffer, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
- * @param inputStream the {@code InputStream} to read.
- * @param outputStream the {@code OutputStream} to write.
+ * @param inputStream the {@link InputStream} to read.
+ * @param outputStream the {@link OutputStream} to write.
* @param buffer the buffer to use for the copy
* @return the number of bytes copied.
* @throws NullPointerException if the InputStream is {@code null}.
@@ -1314,11 +1492,11 @@
}
/**
- * Copies some or all bytes from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}, optionally skipping input bytes.
+ * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}, optionally skipping input bytes.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
* Note that the implementation uses {@link #skip(InputStream, long)}.
@@ -1327,8 +1505,8 @@
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
*
- * @param input the {@code InputStream} to read from
- * @param output the {@code OutputStream} to write to
+ * @param input the {@link InputStream} to read
+ * @param output the {@link OutputStream} to write to
* @param inputOffset : number of bytes to skip from input before copying
* -ve values are ignored
* @param length : number of bytes to copy. -ve means all
@@ -1339,24 +1517,24 @@
*/
public static long copyLarge(final InputStream input, final OutputStream output, final long inputOffset,
final long length) throws IOException {
- return copyLarge(input, output, inputOffset, length, getByteArray());
+ return copyLarge(input, output, inputOffset, length, getScratchByteArray());
}
/**
- * Copies some or all bytes from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}, optionally skipping input bytes.
+ * Copies some or all bytes from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}, optionally skipping input bytes.
*
* This method uses the provided buffer, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
* 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.
*
*
- * @param input the {@code InputStream} to read from
- * @param output the {@code OutputStream} to write to
+ * @param input the {@link InputStream} to read
+ * @param output the {@link OutputStream} to write to
* @param inputOffset : number of bytes to skip from input before copying
* -ve values are ignored
* @param length : number of bytes to copy. -ve means all
@@ -1393,33 +1571,35 @@
}
/**
- * Copies chars from a large (over 2GB) {@code Reader} to a {@code Writer}.
+ * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+ *
*
- * @param reader the {@code Reader} to source.
- * @param writer the {@code Writer} to target.
+ * @param reader the {@link Reader} to source.
+ * @param writer the {@link Writer} to target.
* @return the number of characters copied
* @throws NullPointerException if the input or output is null
* @throws IOException if an I/O error occurs
* @since 1.3
*/
public static long copyLarge(final Reader reader, final Writer writer) throws IOException {
- return copyLarge(reader, writer, getCharArray());
+ return copyLarge(reader, writer, getScratchCharArray());
}
/**
- * Copies chars from a large (over 2GB) {@code Reader} to a {@code Writer}.
+ * Copies chars from a large (over 2GB) {@link Reader} to a {@link Writer}.
*
* This method uses the provided buffer, so there is no need to use a
- * {@code BufferedReader}.
- *
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to source.
- * @param writer the {@code Writer} to target.
+ * @param reader the {@link Reader} to source.
+ * @param writer the {@link Writer} to target.
* @param buffer the buffer to be used for the copy
* @return the number of characters copied
* @throws NullPointerException if the input or output is null
@@ -1437,16 +1617,18 @@
}
/**
- * Copies some or all chars from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}, optionally skipping input chars.
+ * Copies some or all chars from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}, optionally skipping input chars.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
* The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}.
+ *
*
- * @param reader the {@code Reader} to read from
- * @param writer the {@code Writer} to write to
+ * @param reader the {@link Reader} to read
+ * @param writer the {@link Writer} to write to
* @param inputOffset : number of chars to skip from input before copying
* -ve values are ignored
* @param length : number of chars to copy. -ve means all
@@ -1457,19 +1639,19 @@
*/
public static long copyLarge(final Reader reader, final Writer writer, final long inputOffset, final long length)
throws IOException {
- return copyLarge(reader, writer, inputOffset, length, getCharArray());
+ return copyLarge(reader, writer, inputOffset, length, getScratchCharArray());
}
/**
- * Copies some or all chars from a large (over 2GB) {@code InputStream} to an
- * {@code OutputStream}, optionally skipping input chars.
+ * Copies some or all chars from a large (over 2GB) {@link InputStream} to an
+ * {@link OutputStream}, optionally skipping input chars.
*
* This method uses the provided buffer, so there is no need to use a
- * {@code BufferedReader}.
- *
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from
- * @param writer the {@code Writer} to write to
+ * @param reader the {@link Reader} to read
+ * @param writer the {@link Writer} to write to
* @param inputOffset : number of chars to skip from input before copying
* -ve values are ignored
* @param length : number of chars to copy. -ve means all
@@ -1506,24 +1688,64 @@
}
/**
- * Gets the thread local byte array.
+ * Fills the given array with 0s.
*
- * @return the thread local byte array.
+ * @param arr The array to fill.
+ * @return The given array.
*/
- static byte[] getByteArray() {
- return SKIP_BYTE_BUFFER.get();
+ private static byte[] fill0(final byte[] arr) {
+ Arrays.fill(arr, (byte) 0);
+ return arr;
}
/**
- * Gets the thread local char array.
+ * Fills the given array with 0s.
*
- * @return the thread local char array.
+ * @param arr The array to fill.
+ * @return The given array.
*/
- static char[] getCharArray() {
- return SKIP_CHAR_BUFFER.get();
+ private static char[] fill0(final char[] arr) {
+ Arrays.fill(arr, (char) 0);
+ return arr;
}
/**
+ * Gets the internal byte array buffer, intended for both reading and writing.
+ *
+ * @return the internal byte array buffer, intended for both reading and writing.
+ */
+ static byte[] getScratchByteArray() {
+ return fill0(SCRATCH_BYTE_BUFFER_RW.get());
+ }
+
+ /**
+ * Gets the internal byte array intended for write only operations.
+ *
+ * @return the internal byte array intended for write only operations.
+ */
+ static byte[] getScratchByteArrayWriteOnly() {
+ return fill0(SCRATCH_BYTE_BUFFER_WO);
+ }
+
+ /**
+ * Gets the char byte array buffer, intended for both reading and writing.
+ *
+ * @return the char byte array buffer, intended for both reading and writing.
+ */
+ static char[] getScratchCharArray() {
+ return fill0(SCRATCH_CHAR_BUFFER_RW.get());
+ }
+
+ /**
+ * Gets the internal char array intended for write only operations.
+ *
+ * @return the internal char array intended for write only operations.
+ */
+ static char[] getScratchCharArrayWriteOnly() {
+ return fill0(SCRATCH_CHAR_BUFFER_WO);
+ }
+
+ /**
* Returns the length of the given array in a null-safe manner.
*
* @param array an array or null
@@ -1568,16 +1790,18 @@
}
/**
- * Returns an Iterator for the lines in an {@code InputStream}, using
+ * Returns an Iterator for the lines in an {@link InputStream}, using
* the character encoding specified (or default encoding if null).
*
- * {@code LineIterator} holds a reference to the open
- * {@code InputStream} specified here. When you have finished with
+ * {@link LineIterator} holds a reference to the open
+ * {@link InputStream} specified here. When you have finished with
* the iterator you should close the stream to free internal resources.
- * This can be done by closing the stream directly, or by calling
- * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
+ * This can be done by using a try-with-resources block, closing the stream directly, or by calling
+ * {@link LineIterator#close()}.
+ *
*
- * @param input the {@code InputStream} to read from, not null
+ * @param input the {@link InputStream} to read, not null
* @param charset the charset to use, null means platform default
* @return an Iterator of the lines in the reader, never null
* @throws IllegalArgumentException if the input is null
@@ -1601,19 +1825,21 @@
}
/**
- * Returns an Iterator for the lines in an {@code InputStream}, using
+ * Returns an Iterator for the lines in an {@link InputStream}, using
* the character encoding specified (or default encoding if null).
*
- * {@code LineIterator} holds a reference to the open
- * {@code InputStream} specified here. When you have finished with
+ * {@link LineIterator} holds a reference to the open
+ * {@link InputStream} specified here. When you have finished with
* the iterator you should close the stream to free internal resources.
- * This can be done by closing the stream directly, or by calling
- * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
+ * This can be done by using a try-with-resources block, closing the stream directly, or by calling
+ * {@link LineIterator#close()}.
+ *
*
* The recommended usage pattern is:
+ *
*
* try {
- * LineIterator it = IOUtils.lineIterator(stream, "UTF-8");
+ * LineIterator it = IOUtils.lineIterator(stream, StandardCharsets.UTF_8.name());
* while (it.hasNext()) {
* String line = it.nextLine();
* /// do something with line
@@ -1623,7 +1849,7 @@
* }
*
*
- * @param input the {@code InputStream} to read from, not null
+ * @param input the {@link InputStream} to read, not null
* @param charsetName the encoding to use, null means platform default
* @return an Iterator of the lines in the reader, never null
* @throws IllegalArgumentException if the input is null
@@ -1637,15 +1863,17 @@
}
/**
- * Returns an Iterator for the lines in a {@code Reader}.
+ * Returns an Iterator for the lines in a {@link Reader}.
*
- * {@code LineIterator} holds a reference to the open
- * {@code Reader} specified here. When you have finished with the
+ * {@link LineIterator} holds a reference to the open
+ * {@link Reader} specified here. When you have finished with the
* iterator you should close the reader to free internal resources.
- * This can be done by closing the reader directly, or by calling
- * {@link LineIterator#close()} or {@link LineIterator#closeQuietly(LineIterator)}.
+ * This can be done by using a try-with-resources block, closing the reader directly, or by calling
+ * {@link LineIterator#close()}.
+ *
*
- * @param reader the {@code Reader} to read from, not null
+ * @param reader the {@link Reader} to read, not null
* @return an Iterator of the lines in the reader, never null
- * @throws IllegalArgumentException if the reader is null
+ * @throws NullPointerException if the reader is null
* @since 1.2
*/
public static LineIterator lineIterator(final Reader reader) {
@@ -1689,24 +1917,46 @@
* as possible before giving up; this may not always be the case for
* subclasses of {@link InputStream}.
*
- * @param input where to read input from
+ * @param input where to read input
* @param buffer destination
* @param offset initial offset into buffer
* @param length length to read, must be >= 0
* @return actual length read; may be less than requested if EOF was reached
- * @throws IOException if a read error occurs
+ * @throws IllegalArgumentException if length is negative
+ * @throws IOException if a read error occurs
* @since 2.2
*/
public static int read(final InputStream input, final byte[] buffer, final int offset, final int length)
throws IOException {
+ if (length == 0) {
+ return 0;
+ }
+ return read(input::read, buffer, offset, length);
+ }
+
+ /**
+ * Reads bytes from an input. This implementation guarantees that it will read as many bytes as possible before giving up; this may not always be the case
+ * for subclasses of {@link InputStream}.
+ *
+ * @param input How to read input
+ * @param buffer destination
+ * @param offset initial offset into buffer
+ * @param length length to read, must be >= 0
+ * @return actual length read; may be less than requested if EOF was reached
+ * @throws IllegalArgumentException if length is negative
+ * @throws IOException if a read error occurs
+ * @since 2.2
+ */
+ static int read(final IOTriFunction input, final byte[] buffer, final int offset, final int length)
+ throws IOException {
if (length < 0) {
throw new IllegalArgumentException("Length must not be negative: " + length);
}
int remaining = length;
while (remaining > 0) {
final int location = length - remaining;
- final int count = input.read(buffer, offset + location, remaining);
- if (EOF == count) { // EOF
+ final int count = input.apply(buffer, offset + location, remaining);
+ if (EOF == count) {
break;
}
remaining -= count;
@@ -1720,6 +1970,7 @@
* This implementation guarantees that it will read as many bytes
* as possible before giving up; this may not always be the case for
* subclasses of {@link ReadableByteChannel}.
+ *
*
* @param input the byte channel to read
* @param buffer byte buffer destination
@@ -1765,7 +2016,8 @@
* @param offset initial offset into buffer
* @param length length to read, must be >= 0
* @return actual length read; may be less than requested if EOF was reached
- * @throws IOException if a read error occurs
+ * @throws IllegalArgumentException if length is negative
+ * @throws IOException if a read error occurs
* @since 2.2
*/
public static int read(final Reader reader, final char[] buffer, final int offset, final int length)
@@ -1790,6 +2042,7 @@
*
* This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
* not read as many bytes as requested (most likely because of reaching EOF).
+ *
*
* @param input where to read input from
* @param buffer destination
@@ -1808,6 +2061,7 @@
*
* This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
* not read as many bytes as requested (most likely because of reaching EOF).
+ *
*
* @param input where to read input from
* @param buffer destination
@@ -1832,6 +2086,7 @@
*
* This allows for the possibility that {@link InputStream#read(byte[], int, int)} may
* not read as many bytes as requested (most likely because of reaching EOF).
+ *
*
* @param input where to read input from
* @param length length to read, must be >= 0
@@ -1842,7 +2097,7 @@
* @since 2.5
*/
public static byte[] readFully(final InputStream input, final int length) throws IOException {
- final byte[] buffer = IOUtils.byteArray(length);
+ final byte[] buffer = byteArray(length);
readFully(input, buffer, 0, buffer.length);
return buffer;
}
@@ -1852,6 +2107,7 @@
*
* This allows for the possibility that {@link ReadableByteChannel#read(ByteBuffer)} may
* not read as many bytes as requested (most likely because of reaching EOF).
+ *
*
* @param input the byte channel to read
* @param buffer byte buffer destination
@@ -1872,6 +2128,7 @@
*
* This allows for the possibility that {@link Reader#read(char[], int, int)} may
* not read as many characters as requested (most likely because of reaching EOF).
+ *
*
* @param reader where to read input from
* @param buffer destination
@@ -1889,6 +2146,7 @@
*
* This allows for the possibility that {@link Reader#read(char[], int, int)} may
* not read as many characters as requested (most likely because of reaching EOF).
+ *
*
* @param reader where to read input from
* @param buffer destination
@@ -1908,211 +2166,192 @@
}
/**
- * Gets the contents of an {@code InputStream} as a list of Strings,
+ * Gets the contents of an {@link InputStream} as a list of Strings,
* one entry per line, using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param input the {@code InputStream} to read from, not null
+ * @param input the {@link InputStream} to read, not null
* @return the list of Strings, never null
* @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
+ * @throws UncheckedIOException if an I/O error occurs
* @since 1.1
* @deprecated 2.5 use {@link #readLines(InputStream, Charset)} instead
*/
@Deprecated
- public static List readLines(final InputStream input) throws IOException {
+ public static List readLines(final InputStream input) throws UncheckedIOException {
return readLines(input, Charset.defaultCharset());
}
/**
- * Gets the contents of an {@code InputStream} as a list of Strings,
+ * Gets the contents of an {@link InputStream} as a list of Strings,
* one entry per line, using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param input the {@code InputStream} to read from, not null
+ * @param input the {@link InputStream} to read, not null
* @param charset the charset to use, null means platform default
* @return the list of Strings, never null
* @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
+ * @throws UncheckedIOException if an I/O error occurs
* @since 2.3
*/
- public static List readLines(final InputStream input, final Charset charset) throws IOException {
- final InputStreamReader reader = new InputStreamReader(input, Charsets.toCharset(charset));
- return readLines(reader);
+ public static List readLines(final InputStream input, final Charset charset) throws UncheckedIOException {
+ return readLines(new InputStreamReader(input, Charsets.toCharset(charset)));
}
/**
- * Gets the contents of an {@code InputStream} as a list of Strings,
+ * Gets the contents of an {@link InputStream} as a list of Strings,
* one entry per line, using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param input the {@code InputStream} to read from, not null
+ * @param input the {@link InputStream} to read, not null
* @param charsetName the name of the requested charset, null means platform default
* @return the list of Strings, never null
* @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
+ * @throws UncheckedIOException if an I/O error occurs
* @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
* .UnsupportedEncodingException} in version 2.2 if the
* encoding is not supported.
* @since 1.1
*/
- public static List readLines(final InputStream input, final String charsetName) throws IOException {
+ public static List readLines(final InputStream input, final String charsetName) throws UncheckedIOException {
return readLines(input, Charsets.toCharset(charsetName));
}
/**
- * Gets the contents of a {@code Reader} as a list of Strings,
+ * Gets the contents of a {@link Reader} as a list of Strings,
* one entry per line.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from, not null
+ * @param reader the {@link Reader} to read, not null
* @return the list of Strings, never null
* @throws NullPointerException if the input is null
- * @throws IOException if an I/O error occurs
+ * @throws UncheckedIOException if an I/O error occurs
* @since 1.1
*/
@SuppressWarnings("resource") // reader wraps input and is the responsibility of the caller.
- public static List readLines(final Reader reader) throws IOException {
- final BufferedReader bufReader = toBufferedReader(reader);
- final List list = new ArrayList<>();
- String line;
- while ((line = bufReader.readLine()) != null) {
- list.add(line);
- }
- return list;
+ public static List readLines(final Reader reader) throws UncheckedIOException {
+ return toBufferedReader(reader).lines().collect(Collectors.toList());
}
/**
- * Gets the contents of a classpath resource as a byte array.
- *
+ * Gets the contents of a resource as a byte array.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * Delegates to {@link #resourceToByteArray(String, ClassLoader) resourceToByteArray(String, null)}.
*
*
- * @param name name of the desired resource
+ * @param name The resource name.
* @return the requested byte array
- * @throws IOException if an I/O error occurs.
- *
+ * @throws IOException if an I/O error occurs or the resource is not found.
+ * @see #resourceToByteArray(String, ClassLoader)
* @since 2.6
*/
public static byte[] resourceToByteArray(final String name) throws IOException {
return resourceToByteArray(name, null);
}
/**
- * Gets the contents of a classpath resource as a byte array.
- *
+ * Gets the contents of a resource as a byte array.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * Delegates to {@link #resourceToURL(String, ClassLoader)}.
*
*
- * @param name name of the desired resource
+ * @param name The resource name.
* @param classLoader the class loader that the resolution of the resource is delegated to
* @return the requested byte array
- * @throws IOException if an I/O error occurs.
- *
+ * @throws IOException if an I/O error occurs or the resource is not found.
+ * @see #resourceToURL(String, ClassLoader)
* @since 2.6
*/
public static byte[] resourceToByteArray(final String name, final ClassLoader classLoader) throws IOException {
return toByteArray(resourceToURL(name, classLoader));
}
/**
- * Gets the contents of a classpath resource as a String using the
- * specified character encoding.
- *
+ * Gets the contents of a resource as a String using the specified character encoding.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * Delegates to {@link #resourceToString(String, Charset, ClassLoader) resourceToString(String, Charset, null)}.
*
*
- * @param name name of the desired resource
+ * @param name The resource name.
* @param charset the charset to use, null means platform default
* @return the requested String
- * @throws IOException if an I/O error occurs.
- *
+ * @throws IOException if an I/O error occurs or the resource is not found.
+ * @see #resourceToString(String, Charset, ClassLoader)
* @since 2.6
*/
public static String resourceToString(final String name, final Charset charset) throws IOException {
return resourceToString(name, charset, null);
}
/**
- * Gets the contents of a classpath resource as a String using the
- * specified character encoding.
- *
+ * Gets the contents of a resource as a String using the specified character encoding.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * Delegates to {@link #resourceToURL(String, ClassLoader)}.
*
*
- * @param name name of the desired resource
- * @param charset the charset to use, null means platform default
+ * @param name The resource name.
+ * @param charset the Charset to use, null means platform default
* @param classLoader the class loader that the resolution of the resource is delegated to
* @return the requested String
* @throws IOException if an I/O error occurs.
- *
+ * @see #resourceToURL(String, ClassLoader)
* @since 2.6
*/
public static String resourceToString(final String name, final Charset charset, final ClassLoader classLoader) throws IOException {
return toString(resourceToURL(name, classLoader), charset);
}
/**
- * Gets a URL pointing to the given classpath resource.
- *
+ * Gets a URL pointing to the given resource.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * Delegates to {@link #resourceToURL(String, ClassLoader) resourceToURL(String, null)}.
*
*
- * @param name name of the desired resource
- * @return the requested URL
- * @throws IOException if an I/O error occurs.
- *
+ * @param name The resource name.
+ * @return A URL object for reading the resource.
+ * @throws IOException if the resource is not found.
* @since 2.6
*/
public static URL resourceToURL(final String name) throws IOException {
return resourceToURL(name, null);
}
/**
- * Gets a URL pointing to the given classpath resource.
- *
+ * Gets a URL pointing to the given resource.
*
- * It is expected the given {@code name} to be absolute. The
- * behavior is not well-defined otherwise.
+ * If the {@code classLoader} is not null, call {@link ClassLoader#getResource(String)}, otherwise call
+ * {@link Class#getResource(String) IOUtils.class.getResource(name)}.
*
*
- * @param name name of the desired resource
- * @param classLoader the class loader that the resolution of the resource is delegated to
- * @return the requested URL
- * @throws IOException if an I/O error occurs.
- *
+ * @param name The resource name.
+ * @param classLoader Delegate to this class loader if not null
+ * @return A URL object for reading the resource.
+ * @throws IOException if the resource is not found.
* @since 2.6
*/
public static URL resourceToURL(final String name, final ClassLoader classLoader) throws IOException {
// What about the thread context class loader?
// What about the system class loader?
final URL resource = classLoader == null ? IOUtils.class.getResource(name) : classLoader.getResource(name);
-
if (resource == null) {
throw new IOException("Resource not found: " + name);
}
-
return resource;
}
@@ -2138,20 +2377,49 @@
* @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.
+ *
+ * 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.
+ *
+ *
+ * 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}.
+ *
+ *
+ * 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.
+ *
+ *
+ * @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 IO-203 - Add skipFully() method for InputStreams
+ * @since 2.14.0
+ */
+ public static long skip(final InputStream input, final long toSkip, final Supplier skipBufferSupplier) throws IOException {
if (toSkip < 0) {
throw new IllegalArgumentException("Skip count must be non-negative, actual: " + toSkip);
}
- /*
- * N.B. no need to synchronize access to SKIP_BYTE_BUFFER: - we don't care if the buffer is created multiple
- * times (the data is ignored) - we always use the same size buffer, so if it it is recreated it will still be
- * OK (if the buffer size were variable, we would need to synch. to ensure some other thread did not create a
- * smaller one)
- */
+ //
+ // No need to synchronize access to SCRATCH_BYTE_BUFFER_WO: We don't care if the buffer is written multiple
+ // times or in parallel since the data is ignored. We reuse the same buffer, if the buffer size were variable or read-write,
+ // we would need to synch or use a thread local to ensure some other thread safety.
+ //
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 = getByteArray();
- 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;
}
@@ -2218,7 +2486,7 @@
long remain = toSkip;
while (remain > 0) {
// See https://issues.apache.org/jira/browse/IO-203 for why we use read() rather than delegating to skip()
- final char[] charArray = getCharArray();
+ final char[] charArray = getScratchCharArrayWriteOnly();
final long n = reader.read(charArray, 0, (int) Math.min(remain, charArray.length));
if (n < 0) { // EOF
break;
@@ -2233,6 +2501,7 @@
*
* This allows for the possibility that {@link InputStream#skip(long)} may
* not skip as many bytes as requested (most likely because of reaching EOF).
+ *
*
* 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,
@@ -2248,10 +2517,40 @@
* @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.
+ *
+ * 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.
+ *
+ *
+ * This allows for the possibility that {@link InputStream#skip(long)} may not skip as many bytes as requested (most likely because of reaching EOF).
+ *
+ *
+ * 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.
+ *
+ *
+ * @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 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);
}
@@ -2282,6 +2581,7 @@
*
* This allows for the possibility that {@link Reader#skip(long)} may
* not skip as many characters as requested (most likely because of reaching EOF).
+ *
*
* Note that the implementation uses {@link #skip(Reader, long)}.
* This means that the method may be considerably less efficient than using the actual skip implementation,
@@ -2304,20 +2604,23 @@
}
/**
- * Fetches entire contents of an {@code InputStream} and represent
+ * Fetches entire contents of an {@link InputStream} and represent
* same data as result InputStream.
*
* This method is useful where,
+ *
*
*
Source InputStream is slow.
*
It has network resources associated, so we cannot keep it open for
* long time.
*
It has network timeout associated.
*
+ *
* It can be used in favor of {@link #toByteArray(InputStream)}, since it
* avoids unnecessary allocation and copy of byte[].
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
* @param input Stream to be fully buffered.
* @return A fully buffered stream.
@@ -2329,20 +2632,23 @@
}
/**
- * Fetches entire contents of an {@code InputStream} and represent
+ * Fetches entire contents of an {@link InputStream} and represent
* same data as result InputStream.
*
* This method is useful where,
+ *
*
*
Source InputStream is slow.
*
It has network resources associated, so we cannot keep it open for
* long time.
*
It has network timeout associated.
*
+ *
* It can be used in favor of {@link #toByteArray(InputStream)}, since it
* avoids unnecessary allocation and copy of byte[].
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
* @param input Stream to be fully buffered.
* @param size the initial buffer size
@@ -2384,42 +2690,80 @@
}
/**
- * Gets the contents of an {@code InputStream} as a {@code byte[]}.
+ * Gets the contents of an {@link InputStream} as a {@code byte[]}.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
- * @param inputStream the {@code InputStream} to read.
+ * @param inputStream the {@link InputStream} to read.
* @return the requested byte array.
* @throws NullPointerException if the InputStream is {@code null}.
* @throws IOException if an I/O error occurs or reading more than {@link Integer#MAX_VALUE} occurs.
*/
public static byte[] toByteArray(final InputStream inputStream) throws IOException {
// We use a ThresholdingOutputStream to avoid reading AND writing more than Integer.MAX_VALUE.
- try (final UnsynchronizedByteArrayOutputStream ubaOutput = new UnsynchronizedByteArrayOutputStream();
- final ThresholdingOutputStream thresholdOuput = new ThresholdingOutputStream(Integer.MAX_VALUE, os -> {
- throw new IllegalArgumentException(
- String.format("Cannot read more than %,d into a byte array", Integer.MAX_VALUE));
+ try (UnsynchronizedByteArrayOutputStream ubaOutput = UnsynchronizedByteArrayOutputStream.builder().get();
+ ThresholdingOutputStream thresholdOutput = new ThresholdingOutputStream(Integer.MAX_VALUE, os -> {
+ throw new IllegalArgumentException(String.format("Cannot read more than %,d into a byte array", Integer.MAX_VALUE));
}, os -> ubaOutput)) {
- copy(inputStream, thresholdOuput);
+ copy(inputStream, thresholdOutput);
return ubaOutput.toByteArray();
}
}
/**
- * Gets the contents of an {@code InputStream} as a {@code byte[]}. Use this method instead of
- * {@code toByteArray(InputStream)} when {@code InputStream} size is known
+ * Gets the contents of an {@link InputStream} as a {@code byte[]}. Use this method instead of
+ * {@link #toByteArray(InputStream)} when {@link InputStream} size is known.
*
- * @param input the {@code InputStream} to read.
- * @param size the size of {@code InputStream}.
- * @return the requested byte array.
- * @throws IOException if an I/O error occurs or {@code InputStream} size differ from parameter size.
- * @throws IllegalArgumentException if size is less than zero.
+ * @param input the {@link InputStream} to read.
+ * @param size the size of {@link InputStream} to read, where 0 < {@code size} <= length of input stream.
+ * @return byte [] of length {@code size}.
+ * @throws IOException if an I/O error occurs or {@link InputStream} length is smaller than parameter {@code size}.
+ * @throws IllegalArgumentException if {@code size} is less than zero.
* @since 2.1
*/
public static byte[] toByteArray(final InputStream input, final int size) throws IOException {
+ if (size == 0) {
+ return EMPTY_BYTE_ARRAY;
+ }
+ return toByteArray(Objects.requireNonNull(input, "input")::read, size);
+ }
+ /**
+ * Gets contents of an {@link InputStream} as a {@code byte[]}.
+ * Use this method instead of {@link #toByteArray(InputStream)}
+ * when {@link InputStream} size is known.
+ * NOTE: the method checks that the length can safely be cast to an int without truncation
+ * before using {@link IOUtils#toByteArray(InputStream, int)} to read into the byte array.
+ * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
+ *
+ * @param input the {@link InputStream} to read
+ * @param size the size of {@link InputStream} to read, where 0 < {@code size} <= min(Integer.MAX_VALUE, length of input stream).
+ * @return byte [] the requested byte array, of length {@code size}
+ * @throws IOException if an I/O error occurs or {@link InputStream} length is less than {@code size}
+ * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
+ * @see IOUtils#toByteArray(InputStream, int)
+ * @since 2.1
+ */
+ public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
+ if (size > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
+ }
+ return toByteArray(input, (int) size);
+ }
+
+ /**
+ * Gets the contents of an input as a {@code byte[]}.
+ *
+ * @param input the input to read.
+ * @param size the size of the input to read, where 0 < {@code size} <= length of input.
+ * @return byte [] of length {@code size}.
+ * @throws IOException if an I/O error occurs or input length is smaller than parameter {@code size}.
+ * @throws IllegalArgumentException if {@code size} is less than zero.
+ */
+ static byte[] toByteArray(final IOTriFunction input, final int size) throws IOException {
+
if (size < 0) {
throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
}
@@ -2428,11 +2772,11 @@
return EMPTY_BYTE_ARRAY;
}
- final byte[] data = IOUtils.byteArray(size);
+ final byte[] data = byteArray(size);
int offset = 0;
int read;
- while (offset < size && (read = input.read(data, offset, size - offset)) != EOF) {
+ while (offset < size && (read = input.apply(data, offset, size - offset)) != EOF) {
offset += read;
}
@@ -2444,39 +2788,14 @@
}
/**
- * Gets contents of an {@code InputStream} as a {@code byte[]}.
- * Use this method instead of {@code toByteArray(InputStream)}
- * when {@code InputStream} size is known.
- * NOTE: the method checks that the length can safely be cast to an int without truncation
- * before using {@link IOUtils#toByteArray(java.io.InputStream, int)} to read into the byte array.
- * (Arrays can have no more than Integer.MAX_VALUE entries anyway)
- *
- * @param input the {@code InputStream} to read from
- * @param size the size of {@code InputStream}
- * @return the requested byte array
- * @throws IOException if an I/O error occurs or {@code InputStream} size differ from parameter
- * size
- * @throws IllegalArgumentException if size is less than zero or size is greater than Integer.MAX_VALUE
- * @see IOUtils#toByteArray(java.io.InputStream, int)
- * @since 2.1
- */
- public static byte[] toByteArray(final InputStream input, final long size) throws IOException {
-
- if (size > Integer.MAX_VALUE) {
- throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + size);
- }
-
- return toByteArray(input, (int) size);
- }
-
- /**
- * Gets the contents of a {@code Reader} as a {@code byte[]}
+ * Gets the contents of a {@link Reader} as a {@code byte[]}
* using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from
+ * @param reader the {@link Reader} to read
* @return the requested byte array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
@@ -2488,37 +2807,40 @@
}
/**
- * Gets the contents of a {@code Reader} as a {@code byte[]}
+ * Gets the contents of a {@link Reader} as a {@code byte[]}
* using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from
+ * @param reader the {@link Reader} to read
* @param charset the charset to use, null means platform default
* @return the requested byte array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
* @since 2.3
*/
public static byte[] toByteArray(final Reader reader, final Charset charset) throws IOException {
- try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+ try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
copy(reader, output, charset);
return output.toByteArray();
}
}
/**
- * Gets the contents of a {@code Reader} as a {@code byte[]}
+ * Gets the contents of a {@link Reader} as a {@code byte[]}
* using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from
+ * @param reader the {@link Reader} to read
* @param charsetName the name of the requested charset, null means platform default
* @return the requested byte array
* @throws NullPointerException if the input is null
@@ -2533,12 +2855,13 @@
}
/**
- * Gets the contents of a {@code String} as a {@code byte[]}
+ * Gets the contents of a {@link String} as a {@code byte[]}
* using the default character encoding of the platform.
*
* This is the same as {@link String#getBytes()}.
+ *
*
- * @param input the {@code String} to convert
+ * @param input the {@link String} to convert
* @return the requested byte array
* @throws NullPointerException if the input is null
* @deprecated 2.5 Use {@link String#getBytes()} instead
@@ -2550,59 +2873,57 @@
}
/**
- * Gets the contents of a {@code URI} as a {@code byte[]}.
+ * Gets the contents of a {@link URI} as a {@code byte[]}.
*
- * @param uri the {@code URI} to read
+ * @param uri the {@link URI} to read
* @return the requested byte array
* @throws NullPointerException if the uri is null
* @throws IOException if an I/O exception occurs
* @since 2.4
*/
public static byte[] toByteArray(final URI uri) throws IOException {
- return IOUtils.toByteArray(uri.toURL());
+ return toByteArray(uri.toURL());
}
/**
- * Gets the contents of a {@code URL} as a {@code byte[]}.
+ * Gets the contents of a {@link URL} as a {@code byte[]}.
*
- * @param url the {@code URL} to read
+ * @param url the {@link URL} to read
* @return the requested byte array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O exception occurs
* @since 2.4
*/
public static byte[] toByteArray(final URL url) throws IOException {
- final URLConnection conn = url.openConnection();
- try {
- return IOUtils.toByteArray(conn);
- } finally {
- close(conn);
+ try (CloseableURLConnection urlConnection = CloseableURLConnection.open(url)) {
+ return toByteArray(urlConnection);
}
}
/**
- * Gets the contents of a {@code URLConnection} as a {@code byte[]}.
+ * Gets the contents of a {@link URLConnection} as a {@code byte[]}.
*
- * @param urlConn the {@code URLConnection} to read.
+ * @param urlConnection the {@link URLConnection} to read.
* @return the requested byte array.
* @throws NullPointerException if the urlConn is null.
* @throws IOException if an I/O exception occurs.
* @since 2.4
*/
- public static byte[] toByteArray(final URLConnection urlConn) throws IOException {
- try (InputStream inputStream = urlConn.getInputStream()) {
- return IOUtils.toByteArray(inputStream);
+ public static byte[] toByteArray(final URLConnection urlConnection) throws IOException {
+ try (InputStream inputStream = urlConnection.getInputStream()) {
+ return toByteArray(inputStream);
}
}
/**
- * Gets the contents of an {@code InputStream} as a character array
+ * Gets the contents of an {@link InputStream} as a character array
* using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param inputStream the {@code InputStream} to read from
+ * @param inputStream the {@link InputStream} to read
* @return the requested character array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
@@ -2615,13 +2936,14 @@
}
/**
- * Gets the contents of an {@code InputStream} as a character array
+ * Gets the contents of an {@link InputStream} as a character array
* using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param inputStream the {@code InputStream} to read from
+ * @param inputStream the {@link InputStream} to read
* @param charset the charset to use, null means platform default
* @return the requested character array
* @throws NullPointerException if the input is null
@@ -2636,16 +2958,18 @@
}
/**
- * Gets the contents of an {@code InputStream} as a character array
+ * Gets the contents of an {@link InputStream} as a character array
* using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param inputStream the {@code InputStream} to read from
+ * @param inputStream the {@link InputStream} to read
* @param charsetName the name of the requested charset, null means platform default
* @return the requested character array
* @throws NullPointerException if the input is null
@@ -2660,12 +2984,13 @@
}
/**
- * Gets the contents of a {@code Reader} as a character array.
+ * Gets the contents of a {@link Reader} as a character array.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedReader}.
+ *
*
- * @param reader the {@code Reader} to read from
+ * @param reader the {@link Reader} to read
* @return the requested character array
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
@@ -2710,6 +3035,7 @@
*
* Character encoding names can be found at
* IANA.
+ *
*
* @param input the CharSequence to convert
* @param charsetName the name of the requested charset, null means platform default
@@ -2756,6 +3082,7 @@
*
* Character encoding names can be found at
* IANA.
+ *
*
* @param input the string to convert
* @param charsetName the name of the requested charset, null means platform default
@@ -2766,15 +3093,14 @@
* @since 1.1
*/
public static InputStream toInputStream(final String input, final String charsetName) {
- final byte[] bytes = input.getBytes(Charsets.toCharset(charsetName));
- return new ByteArrayInputStream(bytes);
+ return new ByteArrayInputStream(input.getBytes(Charsets.toCharset(charsetName)));
}
/**
* Gets the contents of a {@code byte[]} as a String
* using the default character encoding of the platform.
*
- * @param input the byte array to read from
+ * @param input the byte array to read
* @return the requested String
* @throws NullPointerException if the input is null
* @deprecated 2.5 Use {@link String#String(byte[])} instead
@@ -2791,8 +3117,9 @@
*
* Character encoding names can be found at
* IANA.
+ *
*
- * @param input the byte array to read from
+ * @param input the byte array to read
* @param charsetName the name of the requested charset, null means platform default
* @return the requested String
* @throws NullPointerException if the input is null
@@ -2802,13 +3129,14 @@
}
/**
- * Gets the contents of an {@code InputStream} as a String
+ * Gets the contents of an {@link InputStream} as a String
* using the default character encoding of the platform.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param input the {@code InputStream} to read from
+ * @param input the {@link InputStream} to read
* @return the requested String
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
@@ -2820,38 +3148,40 @@
}
/**
- * Gets the contents of an {@code InputStream} as a String
+ * Gets the contents of an {@link InputStream} as a String
* using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
*
*
- * @param input the {@code InputStream} to read from
+ * @param input the {@link InputStream} to read
* @param charset the charset to use, null means platform default
* @return the requested String
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
* @since 2.3
*/
public static String toString(final InputStream input, final Charset charset) throws IOException {
- try (final StringBuilderWriter sw = new StringBuilderWriter()) {
+ try (StringBuilderWriter sw = new StringBuilderWriter()) {
copy(input, sw, charset);
return sw.toString();
}
}
/**
- * Gets the contents of an {@code InputStream} as a String
+ * Gets the contents of an {@link InputStream} as a String
* using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedInputStream}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param input the {@code InputStream} to read from
+ * @param input the {@link InputStream} to read
* @param charsetName the name of the requested charset, null means platform default
* @return the requested String
* @throws NullPointerException if the input is null
@@ -2866,18 +3196,65 @@
}
/**
- * Gets the contents of a {@code Reader} as a String.
+ * Gets the contents of an {@link InputStream} from a supplier as a String
+ * using the specified character encoding.
*
* This method buffers the input internally, so there is no need to use a
- * {@code BufferedReader}.
+ * {@link BufferedInputStream}.
+ *
*
- * @param reader the {@code Reader} to read from
+ * @param input supplies the {@link InputStream} to read
+ * @param charset the charset to use, null means platform default
* @return the requested String
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
+ * @since 2.12.0
*/
+ public static String toString(final IOSupplier input, final Charset charset) throws IOException {
+ return toString(input, charset, () -> {
+ throw new NullPointerException("input");
+ });
+ }
+
+ /**
+ * Gets the contents of an {@link InputStream} from a supplier as a String
+ * using the specified character encoding.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * {@link BufferedInputStream}.
+ *
+ *
+ * @param input supplies the {@link InputStream} to read
+ * @param charset the charset to use, null means platform default
+ * @param defaultString the default return value if the supplier or its value is null.
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ * @since 2.12.0
+ */
+ public static String toString(final IOSupplier input, final Charset charset, final IOSupplier defaultString) throws IOException {
+ if (input == null) {
+ return defaultString.get();
+ }
+ try (InputStream inputStream = input.get()) {
+ return inputStream != null ? toString(inputStream, charset) : defaultString.get();
+ }
+ }
+
+ /**
+ * Gets the contents of a {@link Reader} as a String.
+ *
+ * This method buffers the input internally, so there is no need to use a
+ * {@link BufferedReader}.
+ *
+ *
+ * @param reader the {@link Reader} to read
+ * @return the requested String
+ * @throws NullPointerException if the input is null
+ * @throws IOException if an I/O error occurs
+ */
public static String toString(final Reader reader) throws IOException {
- try (final StringBuilderWriter sw = new StringBuilderWriter()) {
+ try (StringBuilderWriter sw = new StringBuilderWriter()) {
copy(reader, sw);
return sw.toString();
}
@@ -2950,9 +3327,7 @@
* @since 2.3
*/
public static String toString(final URL url, final Charset encoding) throws IOException {
- try (InputStream inputStream = url.openStream()) {
- return toString(inputStream, encoding);
- }
+ return toString(url::openStream, encoding);
}
/**
@@ -2972,11 +3347,11 @@
}
/**
- * Writes bytes from a {@code byte[]} to an {@code OutputStream}.
+ * Writes bytes from a {@code byte[]} to an {@link OutputStream}.
*
* @param data the byte array to write, do not modify during output,
* null ignored
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -2989,14 +3364,15 @@
}
/**
- * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
+ * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
* using the default character encoding of the platform.
*
* This method uses {@link String#String(byte[])}.
+ *
*
* @param data the byte array to write, do not modify during output,
* null ignored
- * @param writer the {@code Writer} to write to
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3008,14 +3384,15 @@
}
/**
- * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
+ * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
* using the specified character encoding.
*
* This method uses {@link String#String(byte[], String)}.
+ *
*
* @param data the byte array to write, do not modify during output,
* null ignored
- * @param writer the {@code Writer} to write to
+ * @param writer the {@link Writer} to write to
* @param charset the charset to use, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3028,17 +3405,19 @@
}
/**
- * Writes bytes from a {@code byte[]} to chars on a {@code Writer}
+ * Writes bytes from a {@code byte[]} to chars on a {@link Writer}
* using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link String#String(byte[], String)}.
+ *
*
* @param data the byte array to write, do not modify during output,
* null ignored
- * @param writer the {@code Writer} to write to
+ * @param writer the {@link Writer} to write to
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3053,14 +3432,15 @@
/**
* Writes chars from a {@code char[]} to bytes on an
- * {@code OutputStream}.
+ * {@link OutputStream}.
*
* This method uses {@link String#String(char[])} and
* {@link String#getBytes()}.
+ *
*
* @param data the char array to write, do not modify during output,
* null ignored
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3074,38 +3454,41 @@
/**
* Writes chars from a {@code char[]} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * {@link OutputStream} using the specified character encoding.
*
* This method uses {@link String#String(char[])} and
* {@link String#getBytes(String)}.
+ *
*
* @param data the char array to write, do not modify during output,
* null ignored
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @param charset the charset to use, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.3
*/
public static void write(final char[] data, final OutputStream output, final Charset charset) throws IOException {
if (data != null) {
- output.write(new String(data).getBytes(Charsets.toCharset(charset)));
+ write(new String(data), output, charset);
}
}
/**
* Writes chars from a {@code char[]} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * {@link OutputStream} using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link String#String(char[])} and
* {@link String#getBytes(String)}.
+ *
*
* @param data the char array to write, do not modify during output,
* null ignored
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3119,11 +3502,11 @@
}
/**
- * Writes chars from a {@code char[]} to a {@code Writer}
+ * Writes chars from a {@code char[]} to a {@link Writer}
*
* @param data the char array to write, do not modify during output,
* null ignored
- * @param writer the {@code Writer} to write to
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3135,14 +3518,15 @@
}
/**
- * Writes chars from a {@code CharSequence} to bytes on an
- * {@code OutputStream} using the default character encoding of the
+ * Writes chars from a {@link CharSequence} to bytes on an
+ * {@link OutputStream} using the default character encoding of the
* platform.
*
* This method uses {@link String#getBytes()}.
+ *
*
- * @param data the {@code CharSequence} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link CharSequence} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.0
@@ -3155,13 +3539,14 @@
}
/**
- * Writes chars from a {@code CharSequence} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * Writes chars from a {@link CharSequence} to bytes on an
+ * {@link OutputStream} using the specified character encoding.
*
* This method uses {@link String#getBytes(String)}.
+ *
*
- * @param data the {@code CharSequence} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link CharSequence} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @param charset the charset to use, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3175,16 +3560,18 @@
}
/**
- * Writes chars from a {@code CharSequence} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * Writes chars from a {@link CharSequence} to bytes on an
+ * {@link OutputStream} using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link String#getBytes(String)}.
+ *
*
- * @param data the {@code CharSequence} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link CharSequence} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3197,11 +3584,12 @@
write(data, output, Charsets.toCharset(charsetName));
}
+
/**
- * Writes chars from a {@code CharSequence} to a {@code Writer}.
+ * Writes chars from a {@link CharSequence} to a {@link Writer}.
*
- * @param data the {@code CharSequence} to write, null ignored
- * @param writer the {@code Writer} to write to
+ * @param data the {@link CharSequence} to write, null ignored
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.0
@@ -3212,16 +3600,16 @@
}
}
-
/**
- * Writes chars from a {@code String} to bytes on an
- * {@code OutputStream} using the default character encoding of the
+ * Writes chars from a {@link String} to bytes on an
+ * {@link OutputStream} using the default character encoding of the
* platform.
*
* This method uses {@link String#getBytes()}.
+ *
*
- * @param data the {@code String} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link String} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3234,35 +3622,42 @@
}
/**
- * Writes chars from a {@code String} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * Writes chars from a {@link String} to bytes on an
+ * {@link OutputStream} using the specified character encoding.
*
* This method uses {@link String#getBytes(String)}.
+ *
*
- * @param data the {@code String} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link String} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @param charset the charset to use, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.3
*/
+ @SuppressWarnings("resource")
public static void write(final String data, final OutputStream output, final Charset charset) throws IOException {
if (data != null) {
- output.write(data.getBytes(Charsets.toCharset(charset)));
+ // Use Charset#encode(String), since calling String#getBytes(Charset) might result in
+ // NegativeArraySizeException or OutOfMemoryError.
+ // The underlying OutputStream should not be closed, so the channel is not closed.
+ Channels.newChannel(output).write(Charsets.toCharset(charset).encode(data));
}
}
/**
- * Writes chars from a {@code String} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * Writes chars from a {@link String} to bytes on an
+ * {@link OutputStream} using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link String#getBytes(String)}.
+ *
*
- * @param data the {@code String} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link String} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
@@ -3276,10 +3671,10 @@
}
/**
- * Writes chars from a {@code String} to a {@code Writer}.
+ * Writes chars from a {@link String} to a {@link Writer}.
*
- * @param data the {@code String} to write, null ignored
- * @param writer the {@code Writer} to write to
+ * @param data the {@link String} to write, null ignored
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3291,18 +3686,19 @@
}
/**
- * Writes chars from a {@code StringBuffer} to bytes on an
- * {@code OutputStream} using the default character encoding of the
+ * Writes chars from a {@link StringBuffer} to bytes on an
+ * {@link OutputStream} using the default character encoding of the
* platform.
*
* This method uses {@link String#getBytes()}.
+ *
*
- * @param data the {@code StringBuffer} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link StringBuffer} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
- * @deprecated replaced by write(CharSequence, OutputStream)
+ * @deprecated Use {@link #write(CharSequence, OutputStream)}
*/
@Deprecated
public static void write(final StringBuffer data, final OutputStream output) //NOSONAR
@@ -3311,41 +3707,43 @@
}
/**
- * Writes chars from a {@code StringBuffer} to bytes on an
- * {@code OutputStream} using the specified character encoding.
+ * Writes chars from a {@link StringBuffer} to bytes on an
+ * {@link OutputStream} using the specified character encoding.
*
* Character encoding names can be found at
* IANA.
+ *
*
* This method uses {@link String#getBytes(String)}.
+ *
*
- * @param data the {@code StringBuffer} to write, null ignored
- * @param output the {@code OutputStream} to write to
+ * @param data the {@link StringBuffer} to write, null ignored
+ * @param output the {@link OutputStream} to write to
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @throws java.nio.charset.UnsupportedCharsetException thrown instead of {@link java.io
* .UnsupportedEncodingException} in version 2.2 if the encoding is not supported.
* @since 1.1
- * @deprecated replaced by write(CharSequence, OutputStream, String)
+ * @deprecated Use {@link #write(CharSequence, OutputStream, String)}.
*/
@Deprecated
public static void write(final StringBuffer data, final OutputStream output, final String charsetName) //NOSONAR
- throws IOException {
+ throws IOException {
if (data != null) {
- output.write(data.toString().getBytes(Charsets.toCharset(charsetName)));
+ write(data.toString(), output, Charsets.toCharset(charsetName));
}
}
/**
- * Writes chars from a {@code StringBuffer} to a {@code Writer}.
+ * Writes chars from a {@link StringBuffer} to a {@link Writer}.
*
- * @param data the {@code StringBuffer} to write, null ignored
- * @param writer the {@code Writer} to write to
+ * @param data the {@link StringBuffer} to write, null ignored
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 1.1
- * @deprecated replaced by write(CharSequence, Writer)
+ * @deprecated Use {@link #write(CharSequence, Writer)}
*/
@Deprecated
public static void write(final StringBuffer data, final Writer writer) //NOSONAR
@@ -3356,13 +3754,13 @@
}
/**
- * Writes bytes from a {@code byte[]} to an {@code OutputStream} using chunked writes.
+ * Writes bytes from a {@code byte[]} to an {@link OutputStream} using chunked writes.
* This is intended for writing very large byte arrays which might otherwise cause excessive
* memory usage if the native code has to allocate a copy.
*
* @param data the byte array to write, do not modify during output,
* null ignored
- * @param output the {@code OutputStream} to write to
+ * @param output the {@link OutputStream} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.5
@@ -3382,13 +3780,13 @@
}
/**
- * Writes chars from a {@code char[]} to a {@code Writer} using chunked writes.
+ * Writes chars from a {@code char[]} to a {@link Writer} using chunked writes.
* This is intended for writing very large byte arrays which might otherwise cause excessive
* memory usage if the native code has to allocate a copy.
*
* @param data the char array to write, do not modify during output,
* null ignored
- * @param writer the {@code Writer} to write to
+ * @param writer the {@link Writer} to write to
* @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.5
@@ -3407,13 +3805,13 @@
}
/**
- * Writes the {@code toString()} value of each item in a collection to
- * an {@code OutputStream} line by line, using the default character
+ * Writes the {@link #toString()} value of each item in a collection to
+ * an {@link OutputStream} line by line, using the default character
* encoding of the platform and the specified line ending.
*
* @param lines the lines to write, null entries produce blank lines
* @param lineEnding the line separator to use, null is system default
- * @param output the {@code OutputStream} to write to, not null, not closed
+ * @param output the {@link OutputStream} to write to, not null, not closed
* @throws NullPointerException if the output is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3426,46 +3824,56 @@
}
/**
- * Writes the {@code toString()} value of each item in a collection to
- * an {@code OutputStream} line by line, using the specified character
+ * Writes the {@link #toString()} value of each item in a collection to
+ * an {@link OutputStream} line by line, using the specified character
* encoding and the specified line ending.
+ *
+ * UTF-16 is written big-endian with no byte order mark.
+ * For little endian, use UTF-16LE. For a BOM, write it to the stream
+ * before calling this method.
+ *
*
* @param lines the lines to write, null entries produce blank lines
* @param lineEnding the line separator to use, null is system default
- * @param output the {@code OutputStream} to write to, not null, not closed
+ * @param output the {@link OutputStream} to write to, not null, not closed
* @param charset the charset to use, null means platform default
- * @throws NullPointerException if the output is null
+ * @throws NullPointerException if output is null
* @throws IOException if an I/O error occurs
* @since 2.3
*/
public static void writeLines(final Collection> lines, String lineEnding, final OutputStream output,
- final Charset charset) throws IOException {
+ Charset charset) throws IOException {
if (lines == null) {
return;
}
if (lineEnding == null) {
lineEnding = System.lineSeparator();
}
- final Charset cs = Charsets.toCharset(charset);
+ if (StandardCharsets.UTF_16.equals(charset)) {
+ // don't write a BOM
+ charset = StandardCharsets.UTF_16BE;
+ }
+ final byte[] eolBytes = lineEnding.getBytes(charset);
for (final Object line : lines) {
if (line != null) {
- output.write(line.toString().getBytes(cs));
+ write(line.toString(), output, charset);
}
- output.write(lineEnding.getBytes(cs));
+ output.write(eolBytes);
}
}
/**
- * Writes the {@code toString()} value of each item in a collection to
- * an {@code OutputStream} line by line, using the specified character
+ * Writes the {@link #toString()} value of each item in a collection to
+ * an {@link OutputStream} line by line, using the specified character
* encoding and the specified line ending.
*
* Character encoding names can be found at
* IANA.
+ *
*
* @param lines the lines to write, null entries produce blank lines
* @param lineEnding the line separator to use, null is system default
- * @param output the {@code OutputStream} to write to, not null, not closed
+ * @param output the {@link OutputStream} to write to, not null, not closed
* @param charsetName the name of the requested charset, null means platform default
* @throws NullPointerException if the output is null
* @throws IOException if an I/O error occurs
@@ -3480,12 +3888,12 @@
}
/**
- * Writes the {@code toString()} value of each item in a collection to
- * a {@code Writer} line by line, using the specified line ending.
+ * Writes the {@link #toString()} value of each item in a collection to
+ * a {@link Writer} line by line, using the specified line ending.
*
* @param lines the lines to write, null entries produce blank lines
* @param lineEnding the line separator to use, null is system default
- * @param writer the {@code Writer} to write to, not null, not closed
+ * @param writer the {@link Writer} to write to, not null, not closed
* @throws NullPointerException if the input is null
* @throws IOException if an I/O error occurs
* @since 1.1
@@ -3528,9 +3936,10 @@
/**
* Instances should NOT be constructed in standard programming.
+ * @deprecated Will be private in 3.0.
*/
+ @Deprecated
public IOUtils() { //NOSONAR
-
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java (.../LineIterator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/LineIterator.java (.../LineIterator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -22,19 +22,20 @@
import java.io.Reader;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import java.util.Objects;
/**
- * An Iterator over the lines in a {@code Reader}.
+ * An Iterator over the lines in a {@link Reader}.
*
- * {@code LineIterator} holds a reference to an open {@code Reader}.
+ * {@link LineIterator} holds a reference to an open {@link Reader}.
* When you have finished with the iterator you should close the reader
* to free internal resources. This can be done by closing the reader directly,
* or by calling the {@link #close()} or {@link #closeQuietly(LineIterator)}
* method on the iterator.
*
* The recommended usage pattern is:
*
- * LineIterator it = FileUtils.lineIterator(file, "UTF-8");
+ * LineIterator it = FileUtils.lineIterator(file, StandardCharsets.UTF_8.name());
* try {
* while (it.hasNext()) {
* String line = it.nextLine();
@@ -51,23 +52,37 @@
// N.B. This class deliberately does not implement Iterable, see https://issues.apache.org/jira/browse/IO-181
+ /**
+ * Closes a {@link LineIterator} quietly.
+ *
+ * @param iterator The iterator to close, or {@code null}.
+ * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle
+ * suppressed exceptions manually.
+ * @see Throwable#addSuppressed(Throwable)
+ */
+ @Deprecated
+ public static void closeQuietly(final LineIterator iterator) {
+ IOUtils.closeQuietly(iterator);
+ }
+
/** The reader that is being read. */
private final BufferedReader bufferedReader;
+
/** The current line. */
private String cachedLine;
+
/** A flag indicating if the iterator has been fully read. */
private boolean finished;
/**
- * Constructs an iterator of the lines for a {@code Reader}.
+ * Constructs an iterator of the lines for a {@link Reader}.
*
- * @param reader the {@code Reader} to read from, not null
- * @throws IllegalArgumentException if the reader is null
+ * @param reader the {@link Reader} to read from, not null
+ * @throws NullPointerException if the reader is null
*/
- public LineIterator(final Reader reader) throws IllegalArgumentException {
- if (reader == null) {
- throw new IllegalArgumentException("Reader must not be null");
- }
+ @SuppressWarnings("resource") // Caller closes Reader
+ public LineIterator(final Reader reader) {
+ Objects.requireNonNull(reader, "reader");
if (reader instanceof BufferedReader) {
bufferedReader = (BufferedReader) reader;
} else {
@@ -76,8 +91,24 @@
}
/**
- * Indicates whether the {@code Reader} has more lines.
- * If there is an {@code IOException} then {@link #close()} will
+ * Closes the underlying {@link Reader}.
+ * This method is useful if you only want to process the first few
+ * lines of a larger file. If you do not close the iterator
+ * then the {@link Reader} remains open.
+ * This method can safely be called multiple times.
+ *
+ * @throws IOException if closing the underlying {@link Reader} fails.
+ */
+ @Override
+ public void close() throws IOException {
+ finished = true;
+ cachedLine = null;
+ IOUtils.close(bufferedReader);
+ }
+
+ /**
+ * Indicates whether the {@link Reader} has more lines.
+ * If there is an {@link IOException} then {@link #close()} will
* be called on this instance.
*
* @return {@code true} if the Reader has more lines
@@ -103,7 +134,7 @@
return true;
}
}
- } catch(final IOException ioe) {
+ } catch (final IOException ioe) {
IOUtils.closeQuietly(this, ioe::addSuppressed);
throw new IllegalStateException(ioe);
}
@@ -120,7 +151,7 @@
}
/**
- * Returns the next line in the wrapped {@code Reader}.
+ * Returns the next line in the wrapped {@link Reader}.
*
* @return the next line from the input
* @throws NoSuchElementException if there is no line to return
@@ -131,7 +162,7 @@
}
/**
- * Returns the next line in the wrapped {@code Reader}.
+ * Returns the next line in the wrapped {@link Reader}.
*
* @return the next line from the input
* @throws NoSuchElementException if there is no line to return
@@ -146,22 +177,6 @@
}
/**
- * Closes the underlying {@code Reader}.
- * This method is useful if you only want to process the first few
- * lines of a larger file. If you do not close the iterator
- * then the {@code Reader} remains open.
- * This method can safely be called multiple times.
- *
- * @throws IOException if closing the underlying {@code Reader} fails.
- */
- @Override
- public void close() throws IOException {
- finished = true;
- cachedLine = null;
- IOUtils.close(bufferedReader);
- }
-
- /**
* Unsupported.
*
* @throws UnsupportedOperationException always
@@ -171,17 +186,4 @@
throw new UnsupportedOperationException("remove not supported");
}
- /**
- * Closes a {@code LineIterator} quietly.
- *
- * @param iterator The iterator to close, or {@code null}.
- * @deprecated As of 2.6 deprecated without replacement. Please use the try-with-resources statement or handle
- * suppressed exceptions manually.
- * @see Throwable#addSuppressed(java.lang.Throwable)
- */
- @Deprecated
- public static void closeQuietly(final LineIterator iterator) {
- IOUtils.closeQuietly(iterator);
- }
-
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFileMode.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFileMode.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFileMode.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,101 @@
+/*
+ * 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 java.io.File;
+import java.io.FileNotFoundException;
+import java.io.RandomAccessFile;
+import java.nio.file.Path;
+import java.util.Objects;
+
+/**
+ * Access modes and factory methods for {@link RandomAccessFile}.
+ *
+ * @since 2.12.0
+ */
+public enum RandomAccessFileMode {
+
+ /**
+ * Mode {@code "r"} opens for reading only.
+ */
+ READ_ONLY("r"),
+
+ /**
+ * Mode {@code "rw"} opens for reading and writing.
+ */
+ READ_WRITE("rw"),
+
+ /**
+ * Mode {@code "rws"} opens for reading and writing, as with {@code "rw"}, and also require that every update to the file's content or metadata be written
+ * synchronously to the underlying storage device.
+ */
+ READ_WRITE_SYNC_ALL("rws"),
+
+ /**
+ * Mode {@code "rwd"} open for reading and writing, as with {@code "rw"}, and also require that every update to the file's content be written synchronously
+ * to the underlying storage device.
+ */
+ READ_WRITE_SYNC_CONTENT("rwd");
+
+ private final String mode;
+
+ RandomAccessFileMode(final String mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * 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
+ * @return a random access file stream
+ * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}.
+ */
+ public RandomAccessFile create(final File file) throws FileNotFoundException {
+ return new RandomAccessFile(file, mode);
+ }
+
+ /**
+ * 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
+ * @return a random access file stream
+ * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}.
+ */
+ public RandomAccessFile create(final Path file) throws FileNotFoundException {
+ return create(Objects.requireNonNull(file.toFile(), "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
+ * @return a random access file stream
+ * @throws FileNotFoundException See {@link RandomAccessFile#RandomAccessFile(File, String)}.
+ */
+ public RandomAccessFile create(final String file) throws FileNotFoundException {
+ return new RandomAccessFile(file, mode);
+ }
+
+ @Override
+ public String toString() {
+ return mode;
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFiles.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFiles.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/RandomAccessFiles.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,98 @@
+/*
+ * 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 java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.Objects;
+
+import org.apache.commons.io.channels.FileChannels;
+
+/**
+ * Works with {@link RandomAccessFile}.
+ *
+ * @since 2.13.0
+ */
+public class RandomAccessFiles {
+
+ /**
+ * Tests if two RandomAccessFile contents are equal.
+ *
+ * @param raf1 A RandomAccessFile.
+ * @param raf2 Another RandomAccessFile.
+ * @return true if the contents of both RandomAccessFiles are equal, false otherwise.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.15.0
+ */
+ @SuppressWarnings("resource") // See comments
+ public static boolean contentEquals(final RandomAccessFile raf1, final RandomAccessFile raf2) throws IOException {
+ // Short-circuit test
+ if (Objects.equals(raf1, raf2)) {
+ return true;
+ }
+ // Short-circuit test
+ final long length1 = length(raf1);
+ final long length2 = length(raf2);
+ if (length1 != length2) {
+ return false;
+ }
+ if (length1 == 0 && length2 == 0) {
+ return true;
+ }
+ // Dig in and to the work
+ // We do not close FileChannels because that closes the owning RandomAccessFile.
+ // Instead, the caller is assumed to manage the given RandomAccessFile objects.
+ final FileChannel channel1 = raf1.getChannel();
+ final FileChannel channel2 = raf2.getChannel();
+ return FileChannels.contentEquals(channel1, channel2, IOUtils.DEFAULT_BUFFER_SIZE);
+ }
+
+ private static long length(final RandomAccessFile raf) throws IOException {
+ return raf != null ? raf.length() : 0;
+ }
+
+ /**
+ * Reads a byte array starting at "position" for "length" bytes.
+ *
+ * @param input The source RandomAccessFile.
+ * @param position The offset position, measured in bytes from the beginning of the file, at which to set the file pointer.
+ * @param length How many bytes to read.
+ * @return a new byte array.
+ * @throws IOException If the first byte cannot be read for any reason other than end of file, or if the random access file has been closed, or if some
+ * other I/O error occurs.
+ */
+ public static byte[] read(final RandomAccessFile input, final long position, final int length) throws IOException {
+ input.seek(position);
+ return IOUtils.toByteArray(input::read, length);
+ }
+
+ /**
+ * Resets the given file to position 0.
+ *
+ * @param raf The RandomAccessFile to reset.
+ * @return The given RandomAccessFile.
+ * @throws IOException If {@code pos} is less than {@code 0} or if an I/O error occurs.
+ * @since 2.15.0
+ */
+ public static RandomAccessFile reset(final RandomAccessFile raf) throws IOException {
+ raf.seek(0);
+ return raf;
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/StandardLineSeparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/StandardLineSeparator.java (.../StandardLineSeparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/StandardLineSeparator.java (.../StandardLineSeparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -28,7 +28,7 @@
public enum StandardLineSeparator {
/**
- * Carriage return. This is the line ending used on Macos 9 and earlier.
+ * Carriage return. This is the line ending used on Mac OS 9 and earlier.
*/
CR("\r"),
@@ -38,7 +38,7 @@
CRLF("\r\n"),
/**
- * Line feed. This is the line ending used on Linux and Macos X and later.
+ * Line feed. This is the line ending used on Linux and Mac OS X and later.
*/
LF("\n");
Index: 3rdParty_sources/commons-io/org/apache/commons/io/StreamIterator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/StreamIterator.java (.../StreamIterator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/StreamIterator.java (.../StreamIterator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -17,48 +17,75 @@
package org.apache.commons.io;
-import java.io.Closeable;
import java.util.Iterator;
import java.util.Objects;
import java.util.stream.Stream;
/**
- * Wraps and presents a stream as a closable iterator resource that automatically closes itself when reaching the end
- * of stream.
+ * Wraps and presents a {@link Stream} as a {@link AutoCloseable} {@link Iterator} resource that automatically closes itself when reaching the end of stream.
*
- * @param The stream and iterator type.
- * @since 2.9.0
+ *
Warning
+ *
+ * In order to close the stream, the call site MUST either close the stream it allocated OR call this iterator until the end.
+ *
+ *
+ * @param The {@link Stream} and {@link Iterator} type.
+ * @since 2.15.0
*/
-class StreamIterator implements Iterator, Closeable {
+public final class StreamIterator implements Iterator, AutoCloseable {
/**
- * Wraps and presents a stream as a closable resource that automatically closes itself when reaching the end of
- * stream.
- *
Warning
+ * Wraps and presents a stream as a closable resource that automatically closes itself when reaching the end of stream.
*
- * In order to close the stream, the call site MUST either close the stream it allocated OR call the iterator until
- * the end.
+ * Warning
*
+ *
+ * In order to close the stream, the call site MUST either close the stream it allocated OR call this iterator until the end.
+ *
*
- * @param The stream and iterator type.
+ * @param The stream and iterator type.
* @param stream The stream iterate.
* @return A new iterator.
*/
- @SuppressWarnings("resource") // Caller MUST close or iterate to the end.
- public static Iterator iterator(final Stream stream) {
- return new StreamIterator<>(stream).iterator;
+ public static StreamIterator iterator(final Stream stream) {
+ return new StreamIterator<>(stream);
}
+ /**
+ * The given stream's Iterator.
+ */
+ private final Iterator iterator;
+
+ /**
+ * The given stream.
+ */
+ private final Stream stream;
+
+ /**
+ * Whether {@link #close()} has been called.
+ */
+ private boolean closed;
+
private StreamIterator(final Stream stream) {
this.stream = Objects.requireNonNull(stream, "stream");
this.iterator = stream.iterator();
}
- private final Iterator iterator;
- private final Stream stream;
+ /**
+ * Closes the underlying stream.
+ */
+ @Override
+ public void close() {
+ closed = true;
+ stream.close();
+ }
@Override
public boolean hasNext() {
+ if (closed) {
+ // Calling Iterator#hasNext() on a closed java.nio.file.FileTreeIterator causes an IllegalStateException.
+ return false;
+ }
final boolean hasNext = iterator.hasNext();
if (!hasNext) {
close();
@@ -75,13 +102,4 @@
return next;
}
- /**
- * Closes the underlying stream.
- */
- @Override
- public void close() {
- stream.close();
-
- }
-
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java (.../TaggedIOException.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/TaggedIOException.java (.../TaggedIOException.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -103,7 +103,7 @@
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
@@ -114,15 +114,6 @@
}
/**
- * Returns the serializable tag object.
- *
- * @return tag object
- */
- public Serializable getTag() {
- return tag;
- }
-
- /**
* Returns the wrapped exception. The only difference to the overridden
* {@link Throwable#getCause()} method is the narrower return type.
*
@@ -133,4 +124,13 @@
return (IOException) super.getCause();
}
+ /**
+ * Returns the serializable tag object.
+ *
+ * @return tag object
+ */
+ public Serializable getTag() {
+ return tag;
+ }
+
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java (.../ThreadMonitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/ThreadMonitor.java (.../ThreadMonitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -21,118 +21,89 @@
/**
* Monitors a thread, interrupting it if it reaches the specified timeout.
*
- * This works by sleeping until the specified timeout amount and then
- * interrupting the thread being monitored. If the thread being monitored
- * completes its work before being interrupted, it should {@code interrupt()}
- * the monitor thread.
+ * This works by sleeping until the specified timeout amount and then interrupting the thread being monitored. If the
+ * thread being monitored completes its work before being interrupted, it should {@code interrupt()} the monitor
+ * thread.
*
*
*
- * long timeoutInMillis = 1000;
- * try {
- * Thread monitor = ThreadMonitor.start(timeoutInMillis);
- * // do some work here
- * ThreadMonitor.stop(monitor);
- * } catch (InterruptedException e) {
- * // timed amount was reached
- * }
+ * Duration timeout = Duration.ofSeconds(1);
+ * try {
+ * Thread monitor = ThreadMonitor.start(timeout);
+ * // do some work here
+ * ThreadMonitor.stop(monitor);
+ * } catch (InterruptedException e) {
+ * // timed amount was reached
+ * }
*
- *
*/
-class ThreadMonitor implements Runnable {
+final class ThreadMonitor implements Runnable {
- private final Thread thread;
- private final Duration timeout;
-
/**
- * Start monitoring the current thread.
+ * Starts monitoring the current thread.
*
- * @param timeout The timeout amount in milliseconds
- * or no timeout if the value is zero or less
- * @return The monitor thread or {@code null}
- * if the timeout amount is not greater than zero
+ * @param timeout The timeout amount. or no timeout if the value is zero or less.
+ * @return The monitor thread or {@code null} if the timeout amount is not greater than zero.
*/
static Thread start(final Duration timeout) {
return start(Thread.currentThread(), timeout);
}
/**
- * Start monitoring the specified thread.
+ * Starts monitoring the specified thread.
*
- * @param thread The thread The thread to monitor
- * @param timeout The timeout amount in milliseconds
- * or no timeout if the value is zero or less
- * @return The monitor thread or {@code null}
- * if the timeout amount is not greater than zero
+ * @param thread The thread to monitor
+ * @param timeout The timeout amount. or no timeout if the value is zero or less.
+ * @return The monitor thread or {@code null} if the timeout amount is not greater than zero.
*/
static Thread start(final Thread thread, final Duration timeout) {
if (timeout.isZero() || timeout.isNegative()) {
return null;
}
- final ThreadMonitor timout = new ThreadMonitor(thread, timeout);
- final Thread monitor = new Thread(timout, ThreadMonitor.class.getSimpleName());
+ final Thread monitor = new Thread(new ThreadMonitor(thread, timeout), ThreadMonitor.class.getSimpleName());
monitor.setDaemon(true);
monitor.start();
return monitor;
}
/**
- * Stop monitoring the specified thread.
+ * Stops monitoring the specified thread.
*
- * @param thread The monitor thread, may be {@code null}
+ * @param thread The monitor thread, may be {@code null}.
*/
static void stop(final Thread thread) {
if (thread != null) {
thread.interrupt();
}
}
+ private final Thread thread;
+
+ private final Duration timeout;
+
/**
* Constructs a new monitor.
*
- * @param thread The thread to monitor
- * @param timeout The timeout amount in milliseconds
+ * @param thread The thread to monitor.
+ * @param timeout The timeout amount.
*/
private ThreadMonitor(final Thread thread, final Duration timeout) {
this.thread = thread;
this.timeout = timeout;
}
/**
- * Sleep until the specified timeout amount and then
- * interrupt the thread being monitored.
+ * Sleeps until the specified timeout amount and then interrupt the thread being monitored.
*
* @see Runnable#run()
*/
@Override
public void run() {
try {
- sleep(timeout);
+ ThreadUtils.sleep(timeout);
thread.interrupt();
} catch (final InterruptedException e) {
// timeout not reached
}
}
-
- /**
- * Sleeps for a guaranteed minimum duration unless interrupted.
- *
- * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else
- * it deems appropriate. Read the docs on Thread.sleep for further interesting details.
- *
- * @param duration the sleep duration.
- * @throws InterruptedException if interrupted
- */
- private static void sleep(final Duration duration) throws InterruptedException {
- // Ignore nanos for now.
- final long millis = duration.toMillis();
- final long finishAtMillis = System.currentTimeMillis() + millis;
- long remainingMillis = millis;
- do {
- Thread.sleep(remainingMillis);
- remainingMillis = finishAtMillis - System.currentTimeMillis();
- } while (remainingMillis > 0);
- }
-
-
-}
\ No newline at end of file
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/ThreadUtils.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/ThreadUtils.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/ThreadUtils.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,54 @@
+/*
+ * 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 java.time.Duration;
+import java.time.Instant;
+
+/**
+ * Helps work with threads.
+ *
+ * @since 2.12.0
+ */
+public final class ThreadUtils {
+
+ private static int getNanosOfMilli(final Duration duration) {
+ return duration.getNano() % 1_000_000;
+ }
+
+ /**
+ * Sleeps for a guaranteed minimum duration unless interrupted.
+ *
+ * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else it deems appropriate. Read
+ * {@link Thread#sleep(long, int)}} for further interesting details.
+ *
+ *
+ * @param duration the sleep duration.
+ * @throws InterruptedException if interrupted
+ * @see Thread#sleep(long, int)
+ */
+ public static void sleep(final Duration duration) throws InterruptedException {
+ // Using this method avoids depending on the vagaries of the precision and accuracy of system timers and schedulers.
+ final Instant finishInstant = Instant.now().plus(duration);
+ Duration remainingDuration = duration;
+ do {
+ Thread.sleep(remainingDuration.toMillis(), getNanosOfMilli(remainingDuration));
+ remainingDuration = Duration.between(Instant.now(), finishInstant);
+ } while (!remainingDuration.isNegative());
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/UncheckedIOExceptions.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/UncheckedIOExceptions.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/UncheckedIOExceptions.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,62 @@
+/*
+ * 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 java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Objects;
+
+/**
+ * Helps use lambdas that throw {@link IOException} rethrow as {@link UncheckedIOException}.
+ *
+ * @since 2.12.0
+ */
+final class UncheckedIOExceptions {
+
+ /**
+ * Constructs a new UncheckedIOException for the given detail message.
+ *
+ * This method exists because there is no String constructor in {@link UncheckedIOException}.
+ *
+ *
+ * @param message the detail message.
+ * @return a new {@link UncheckedIOException}.
+ */
+ public static UncheckedIOException create(final Object message) {
+ final String string = Objects.toString(message);
+ return new UncheckedIOException(string, new IOException(string));
+ }
+
+ /**
+ * Constructs a new UncheckedIOException for the given detail message.
+ *
+ * This method exists because there is no String constructor in {@link UncheckedIOException}.
+ *
+ * @param e cause the {@link IOException}.
+ * @param message the detail message.
+ *
+ * @return a new {@link UncheckedIOException}.
+ */
+ public static UncheckedIOException wrap(final IOException e, final Object message) {
+ return new UncheckedIOException(Objects.toString(message), e);
+ }
+
+ private UncheckedIOExceptions() {
+ // no instance
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOrigin.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOrigin.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOrigin.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,530 @@
+/*
+ * 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 java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Objects;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.RandomAccessFileMode;
+import org.apache.commons.io.RandomAccessFiles;
+import org.apache.commons.io.input.ReaderInputStream;
+import org.apache.commons.io.output.WriterOutputStream;
+
+/**
+ * Abstracts the origin of data for builders like a {@link File}, {@link Path}, {@link Reader}, {@link Writer}, {@link InputStream}, {@link OutputStream}, and
+ * {@link URI}.
+ *
+ * Some methods may throw {@link UnsupportedOperationException} if that method is not implemented in a concrete subclass, see {@link #getFile()} and
+ * {@link #getPath()}.
+ *
+ *
+ * @param the type of instances to build.
+ * @param the type of builder subclass.
+ * @since 2.12.0
+ */
+public abstract class AbstractOrigin> extends AbstractSupplier {
+
+ /**
+ * A {@code byte[]} origin.
+ */
+ public static class ByteArrayOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public ByteArrayOrigin(final byte[] origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray() {
+ // No conversion
+ return get();
+ }
+
+ @Override
+ public InputStream getInputStream(final OpenOption... options) throws IOException {
+ return new ByteArrayInputStream(origin);
+ }
+
+ @Override
+ public Reader getReader(final Charset charset) throws IOException {
+ return new InputStreamReader(getInputStream(), charset);
+ }
+
+ @Override
+ public long size() throws IOException {
+ return origin.length;
+ }
+
+ }
+
+ /**
+ * A {@link CharSequence} origin.
+ */
+ public static class CharSequenceOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public CharSequenceOrigin(final CharSequence origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray() {
+ // TODO Pass in a Charset? Consider if call sites actually need this.
+ return origin.toString().getBytes(Charset.defaultCharset());
+ }
+
+ @Override
+ public CharSequence getCharSequence(final Charset charset) {
+ // No conversion
+ return get();
+ }
+
+ @Override
+ public InputStream getInputStream(final OpenOption... options) throws IOException {
+ // TODO Pass in a Charset? Consider if call sites actually need this.
+ return new ByteArrayInputStream(origin.toString().getBytes(Charset.defaultCharset()));
+ // Needs [IO-795] CharSequenceInputStream.reset() only works once.
+ // return CharSequenceInputStream.builder().setCharSequence(getCharSequence(Charset.defaultCharset())).get();
+ }
+
+ @Override
+ public Reader getReader(final Charset charset) throws IOException {
+ return new InputStreamReader(getInputStream(), charset);
+ }
+
+ @Override
+ public long size() throws IOException {
+ return origin.length();
+ }
+
+ }
+
+ /**
+ * A {@link File} origin.
+ *
+ * Starting from this origin, you can get a byte array, a file, an input stream, an output stream, a path, a reader, and a writer.
+ *
+ */
+ public static class FileOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public FileOrigin(final File origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray(final long position, final int length) throws IOException {
+ try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) {
+ return RandomAccessFiles.read(raf, position, length);
+ }
+ }
+
+ @Override
+ public File getFile() {
+ // No conversion
+ return get();
+ }
+
+ @Override
+ public Path getPath() {
+ return get().toPath();
+ }
+
+ }
+
+ /**
+ * An {@link InputStream} origin.
+ *
+ * This origin cannot provide some of the other aspects.
+ *
+ */
+ public static class InputStreamOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public InputStreamOrigin(final InputStream origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray() throws IOException {
+ return IOUtils.toByteArray(origin);
+ }
+
+ @Override
+ public InputStream getInputStream(final OpenOption... options) {
+ // No conversion
+ return get();
+ }
+
+ @Override
+ public Reader getReader(final Charset charset) throws IOException {
+ return new InputStreamReader(getInputStream(), charset);
+ }
+
+ }
+
+ /**
+ * An {@link OutputStream} origin.
+ *
+ * This origin cannot provide some of the other aspects.
+ *
+ */
+ public static class OutputStreamOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public OutputStreamOrigin(final OutputStream origin) {
+ super(origin);
+ }
+
+ @Override
+ public OutputStream getOutputStream(final OpenOption... options) {
+ // No conversion
+ return get();
+ }
+
+ @Override
+ public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
+ return new OutputStreamWriter(origin, charset);
+ }
+ }
+
+ /**
+ * A {@link Path} origin.
+ *
+ * Starting from this origin, you can get a byte array, a file, an input stream, an output stream, a path, a reader, and a writer.
+ *
+ */
+ public static class PathOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public PathOrigin(final Path origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray(final long position, final int length) throws IOException {
+ try (RandomAccessFile raf = RandomAccessFileMode.READ_ONLY.create(origin)) {
+ return RandomAccessFiles.read(raf, position, length);
+ }
+ }
+
+ @Override
+ public File getFile() {
+ return get().toFile();
+ }
+
+ @Override
+ public Path getPath() {
+ // No conversion
+ return get();
+ }
+
+ }
+
+ /**
+ * An {@link Reader} origin.
+ *
+ * This origin cannot provide other aspects.
+ *
+ */
+ public static class ReaderOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public ReaderOrigin(final Reader origin) {
+ super(origin);
+ }
+
+ @Override
+ public byte[] getByteArray() throws IOException {
+ // TODO Pass in a Charset? Consider if call sites actually need this.
+ return IOUtils.toByteArray(origin, Charset.defaultCharset());
+ }
+
+ @Override
+ public CharSequence getCharSequence(final Charset charset) throws IOException {
+ return IOUtils.toString(origin);
+ }
+
+ @Override
+ public InputStream getInputStream(final OpenOption... options) throws IOException {
+ // TODO Pass in a Charset? Consider if call sites actually need this.
+ return ReaderInputStream.builder().setReader(origin).setCharset(Charset.defaultCharset()).get();
+ }
+
+ @Override
+ public Reader getReader(final Charset charset) throws IOException {
+ // No conversion
+ return get();
+ }
+ }
+
+ /**
+ * A {@link URI} origin.
+ */
+ public static class URIOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public URIOrigin(final URI origin) {
+ super(origin);
+ }
+
+ @Override
+ public File getFile() {
+ return getPath().toFile();
+ }
+
+ @Override
+ public Path getPath() {
+ return Paths.get(get());
+ }
+
+ }
+
+ /**
+ * An {@link Writer} origin.
+ *
+ * This origin cannot provide other aspects.
+ *
+ */
+ public static class WriterOrigin extends AbstractOrigin {
+
+ /**
+ * Constructs a new instance for the given origin.
+ *
+ * @param origin The origin.
+ */
+ public WriterOrigin(final Writer origin) {
+ super(origin);
+ }
+
+ @Override
+ public OutputStream getOutputStream(final OpenOption... options) throws IOException {
+ // TODO Pass in a Charset? Consider if call sites actually need this.
+ return WriterOutputStream.builder().setWriter(origin).setCharset(Charset.defaultCharset()).get();
+ }
+
+ @Override
+ public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
+ // No conversion
+ return get();
+ }
+ }
+
+ /**
+ * The non-null origin.
+ */
+ final T origin;
+
+ /**
+ * Constructs a new instance for a subclass.
+ *
+ * @param origin The origin.
+ */
+ protected AbstractOrigin(final T origin) {
+ this.origin = Objects.requireNonNull(origin, "origin");
+ }
+
+ /**
+ * Gets the origin.
+ *
+ * @return the origin.
+ */
+ @Override
+ public T get() {
+ return origin;
+ }
+
+ /**
+ * Gets this origin as a byte array, if possible.
+ *
+ * @return this origin as a byte array, if possible.
+ * @throws IOException if an I/O error occurs.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ */
+ public byte[] getByteArray() throws IOException {
+ return Files.readAllBytes(getPath());
+ }
+
+ /**
+ * Gets this origin as a byte array, if possible.
+ *
+ * @param position the initial index of the range to be copied, inclusive.
+ * @param length How many bytes to copy.
+ * @return this origin as a byte array, if possible.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ * @throws ArithmeticException if the {@code position} overflows an int
+ * @throws IOException if an I/O error occurs.
+ * @since 2.13.0
+ */
+ public byte[] getByteArray(final long position, final int length) throws IOException {
+ final byte[] bytes = getByteArray();
+ // Checks for int overflow.
+ final int start = Math.toIntExact(position);
+ if (start < 0 || length < 0 || start + length < 0 || start + length > bytes.length) {
+ throw new IllegalArgumentException("Couldn't read array (start: " + start + ", length: " + length + ", data length: " + bytes.length + ").");
+ }
+ return Arrays.copyOfRange(bytes, start, start + length);
+ }
+
+ /**
+ * Gets this origin as a byte array, if possible.
+ *
+ * @param charset The charset to use if conversion from bytes is needed.
+ * @return this origin as a byte array, if possible.
+ * @throws IOException if an I/O error occurs.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ */
+ public CharSequence getCharSequence(final Charset charset) throws IOException {
+ return new String(getByteArray(), charset);
+ }
+
+ /**
+ * Gets this origin as a Path, if possible.
+ *
+ * @return this origin as a Path, if possible.
+ * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass.
+ */
+ public File getFile() {
+ throw new UnsupportedOperationException(
+ String.format("%s#getFile() for %s origin %s", getClass().getSimpleName(), origin.getClass().getSimpleName(), origin));
+ }
+
+ /**
+ * Gets this origin as an InputStream, if possible.
+ *
+ * @param options options specifying how the file is opened
+ * @return this origin as an InputStream, if possible.
+ * @throws IOException if an I/O error occurs.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ */
+ public InputStream getInputStream(final OpenOption... options) throws IOException {
+ return Files.newInputStream(getPath(), options);
+ }
+
+ /**
+ * Gets this origin as an OutputStream, if possible.
+ *
+ * @param options options specifying how the file is opened
+ * @return this origin as an OutputStream, if possible.
+ * @throws IOException if an I/O error occurs.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ */
+ public OutputStream getOutputStream(final OpenOption... options) throws IOException {
+ return Files.newOutputStream(getPath(), options);
+ }
+
+ /**
+ * Gets this origin as a Path, if possible.
+ *
+ * @return this origin as a Path, if possible.
+ * @throws UnsupportedOperationException if this method is not implemented in a concrete subclass.
+ */
+ public Path getPath() {
+ throw new UnsupportedOperationException(
+ String.format("%s#getPath() for %s origin %s", getClass().getSimpleName(), origin.getClass().getSimpleName(), origin));
+ }
+
+ /**
+ * Gets a new Reader on the origin, buffered by default.
+ *
+ * @param charset the charset to use for decoding
+ * @return a new Reader on the origin.
+ * @throws IOException if an I/O error occurs opening the file.
+ */
+ public Reader getReader(final Charset charset) throws IOException {
+ return Files.newBufferedReader(getPath(), charset);
+ }
+
+ /**
+ * Gets a new Writer on the origin, buffered by default.
+ *
+ * @param charset the charset to use for encoding
+ * @param options options specifying how the file is opened
+ * @return a new Writer on the origin.
+ * @throws IOException if an I/O error occurs opening or creating the file.
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ */
+ public Writer getWriter(final Charset charset, final OpenOption... options) throws IOException {
+ return Files.newBufferedWriter(getPath(), charset, options);
+ }
+
+ /**
+ * Gets the size of the origin, if possible.
+ *
+ * @return the size of the origin in bytes or characters.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.13.0
+ */
+ public long size() throws IOException {
+ return Files.size(getPath());
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + origin.toString() + "]";
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOriginSupplier.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOriginSupplier.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractOriginSupplier.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,316 @@
+/*
+ * 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 java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.URI;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.apache.commons.io.build.AbstractOrigin.ByteArrayOrigin;
+import org.apache.commons.io.build.AbstractOrigin.CharSequenceOrigin;
+import org.apache.commons.io.build.AbstractOrigin.FileOrigin;
+import org.apache.commons.io.build.AbstractOrigin.InputStreamOrigin;
+import org.apache.commons.io.build.AbstractOrigin.OutputStreamOrigin;
+import org.apache.commons.io.build.AbstractOrigin.PathOrigin;
+import org.apache.commons.io.build.AbstractOrigin.ReaderOrigin;
+import org.apache.commons.io.build.AbstractOrigin.URIOrigin;
+import org.apache.commons.io.build.AbstractOrigin.WriterOrigin;
+
+/**
+ * Abstracts building an instance of {@code T}.
+ *
+ * @param the type of instances to build.
+ * @param the type of builder subclass.
+ * @since 2.12.0
+ */
+public abstract class AbstractOriginSupplier> extends AbstractSupplier {
+
+ /**
+ * Constructs a new byte array origin for a byte array.
+ *
+ * @param origin the byte array.
+ * @return a new byte array origin.
+ */
+ protected static ByteArrayOrigin newByteArrayOrigin(final byte[] origin) {
+ return new ByteArrayOrigin(origin);
+ }
+
+ /**
+ * Constructs a new CharSequence origin for a CharSequence.
+ *
+ * @param origin the CharSequence.
+ * @return a new file origin.
+ * @since 2.13.0
+ */
+ protected static CharSequenceOrigin newCharSequenceOrigin(final CharSequence origin) {
+ return new CharSequenceOrigin(origin);
+ }
+
+ /**
+ * Constructs a new file origin for a file.
+ *
+ * @param origin the file.
+ * @return a new file origin.
+ */
+ protected static FileOrigin newFileOrigin(final File origin) {
+ return new FileOrigin(origin);
+ }
+
+ /**
+ * Constructs a new file origin for a file path.
+ *
+ * @param origin the file path.
+ * @return a new file origin.
+ */
+ protected static FileOrigin newFileOrigin(final String origin) {
+ return new FileOrigin(new File(origin));
+ }
+
+ /**
+ * Constructs a new input stream origin for a file.
+ *
+ * @param origin the input stream.
+ * @return a new input stream origin.
+ */
+ protected static InputStreamOrigin newInputStreamOrigin(final InputStream origin) {
+ return new InputStreamOrigin(origin);
+ }
+
+ /**
+ * Constructs a new output stream origin for a file.
+ *
+ * @param origin the output stream.
+ * @return a new output stream origin.
+ */
+ protected static OutputStreamOrigin newOutputStreamOrigin(final OutputStream origin) {
+ return new OutputStreamOrigin(origin);
+ }
+
+ /**
+ * Constructs a new path origin for a file.
+ *
+ * @param origin the path.
+ * @return a new path origin.
+ */
+ protected static PathOrigin newPathOrigin(final Path origin) {
+ return new PathOrigin(origin);
+ }
+
+ /**
+ * Constructs a new path name origin for a path name.
+ *
+ * @param origin the path name.
+ * @return a new path name origin.
+ */
+ protected static PathOrigin newPathOrigin(final String origin) {
+ return new PathOrigin(Paths.get(origin));
+ }
+
+ /**
+ * Constructs a new reader origin for a reader.
+ *
+ * @param origin the reader.
+ * @return a new reader origin.
+ */
+ protected static ReaderOrigin newReaderOrigin(final Reader origin) {
+ return new ReaderOrigin(origin);
+ }
+
+ /**
+ * Constructs a new reader origin for a URI.
+ *
+ * @param origin the URI.
+ * @return a new URI origin.
+ */
+ protected static URIOrigin newURIOrigin(final URI origin) {
+ return new URIOrigin(origin);
+ }
+
+ /**
+ * Constructs a new writer origin for a file.
+ *
+ * @param origin the writer.
+ * @return a new writer .
+ */
+ protected static WriterOrigin newWriterOrigin(final Writer origin) {
+ return new WriterOrigin(origin);
+ }
+
+ /**
+ * The underlying origin.
+ */
+ private AbstractOrigin, ?> origin;
+
+ /**
+ * Checks whether the origin is null.
+ *
+ * @return the origin.
+ * @throws IllegalStateException if the {@code origin} is {@code null}.
+ */
+ protected AbstractOrigin, ?> checkOrigin() {
+ if (origin == null) {
+ throw new IllegalStateException("origin == null");
+ }
+ return origin;
+ }
+
+ /**
+ * Gets the origin.
+ *
+ * @return the origin.
+ */
+ protected AbstractOrigin, ?> getOrigin() {
+ return origin;
+ }
+
+ /**
+ * Tests whether the origin is null.
+ *
+ * @return whether the origin is null.
+ */
+ protected boolean hasOrigin() {
+ return origin != null;
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setByteArray(final byte[] origin) {
+ return setOrigin(newByteArrayOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ * @since 2.13.0
+ */
+ public B setCharSequence(final CharSequence origin) {
+ return setOrigin(newCharSequenceOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setFile(final File origin) {
+ return setOrigin(newFileOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setFile(final String origin) {
+ return setOrigin(newFileOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setInputStream(final InputStream origin) {
+ return setOrigin(newInputStreamOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ protected B setOrigin(final AbstractOrigin, ?> origin) {
+ this.origin = origin;
+ return asThis();
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setOutputStream(final OutputStream origin) {
+ return setOrigin(newOutputStreamOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setPath(final Path origin) {
+ return setOrigin(newPathOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setPath(final String origin) {
+ return setOrigin(newPathOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setReader(final Reader origin) {
+ return setOrigin(newReaderOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setURI(final URI origin) {
+ return setOrigin(newURIOrigin(origin));
+ }
+
+ /**
+ * Sets a new origin.
+ *
+ * @param origin the new origin.
+ * @return this
+ */
+ public B setWriter(final Writer origin) {
+ return setOrigin(newWriterOrigin(origin));
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractStreamBuilder.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractStreamBuilder.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractStreamBuilder.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,339 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+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;
+import org.apache.commons.io.file.PathUtils;
+
+/**
+ * Abstracts building a typed instance of {@code T}.
+ *
+ * @param the type of instances to build.
+ * @param the type of builder subclass.
+ * @since 2.12.0
+ */
+public abstract class AbstractStreamBuilder> extends AbstractOriginSupplier {
+
+ private static final int DEFAULT_MAX_VALUE = Integer.MAX_VALUE;
+
+ private static final OpenOption[] DEFAULT_OPEN_OPTIONS = PathUtils.EMPTY_OPEN_OPTION_ARRAY;
+
+ /**
+ * The buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}).
+ */
+ private int bufferSize = IOUtils.DEFAULT_BUFFER_SIZE;
+
+ /**
+ * The buffer size, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}).
+ */
+ 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();
+
+ /**
+ * The Charset, defaults to {@link Charset#defaultCharset()}.
+ */
+ private Charset charsetDefault = Charset.defaultCharset();
+
+ 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}).
+ */
+ protected int getBufferSize() {
+ return bufferSize;
+ }
+
+ /**
+ * Gets the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}).
+ *
+ * @return the buffer size default, defaults to {@link IOUtils#DEFAULT_BUFFER_SIZE} ({@value IOUtils#DEFAULT_BUFFER_SIZE}).
+ */
+ protected int getBufferSizeDefault() {
+ return bufferSizeDefault;
+ }
+
+ /**
+ * Gets a CharSequence from the origin with a Charset.
+ *
+ * @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}.
+ * @see AbstractOrigin#getCharSequence(Charset)
+ * @since 2.13.0
+ */
+ protected CharSequence getCharSequence() throws IOException {
+ return checkOrigin().getCharSequence(getCharset());
+ }
+
+ /**
+ * Gets the Charset, defaults to {@link Charset#defaultCharset()}.
+ *
+ * @return the Charset, defaults to {@link Charset#defaultCharset()}.
+ */
+ public Charset getCharset() {
+ return charset;
+ }
+
+ /**
+ * Gets the Charset default, defaults to {@link Charset#defaultCharset()}.
+ *
+ * @return the Charset default, defaults to {@link Charset#defaultCharset()}.
+ */
+ protected Charset getCharsetDefault() {
+ return charsetDefault;
+ }
+
+ /**
+ * Gets an input stream from the origin with open options.
+ *
+ * @return An input stream
+ * @throws IOException if an I/O error occurs.
+ * @throws UnsupportedOperationException if the origin cannot be converted to an InputStream.
+ * @see AbstractOrigin#getInputStream(OpenOption...)
+ * @throws IllegalStateException if the {@code origin} is {@code null}.
+ * @since 2.13.0
+ */
+ protected InputStream getInputStream() throws IOException {
+ return checkOrigin().getInputStream(getOpenOptions());
+ }
+
+ /**
+ * Gets the OpenOption.
+ *
+ * @return the OpenOption.
+ */
+ protected OpenOption[] getOpenOptions() {
+ return openOptions;
+ }
+
+ /**
+ * Gets an OutputStream from the origin with open options.
+ *
+ * @return An OutputStream
+ * @throws IOException if an I/O error occurs.
+ * @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
+ */
+ protected OutputStream getOutputStream() throws IOException {
+ return checkOrigin().getOutputStream(getOpenOptions());
+ }
+
+ /**
+ * Gets a Path from the origin.
+ *
+ * @return A Path
+ * @throws UnsupportedOperationException if the origin cannot be converted to a Path.
+ * @throws IllegalStateException if the {@code origin} is {@code null}.
+ * @see AbstractOrigin#getPath()
+ * @since 2.13.0
+ */
+ protected Path getPath() {
+ return checkOrigin().getPath();
+ }
+
+ /**
+ * Gets an writer from the origin with open options.
+ *
+ * @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}.
+ * @see AbstractOrigin#getOutputStream(OpenOption...)
+ * @since 2.13.0
+ */
+ protected Writer getWriter() throws IOException {
+ return checkOrigin().getWriter(getCharset(), getOpenOptions());
+ }
+
+ /**
+ * Sets the buffer size. Invalid input (bufferSize <= 0) resets the value to its default.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param bufferSize the buffer size.
+ * @return this.
+ */
+ public B setBufferSize(final int bufferSize) {
+ this.bufferSize = checkBufferSize(bufferSize > 0 ? bufferSize : bufferSizeDefault);
+ return asThis();
+ }
+
+ /**
+ * Sets the buffer size.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param bufferSize the buffer size, null resets to the default.
+ * @return this.
+ */
+ public B setBufferSize(final Integer bufferSize) {
+ setBufferSize(bufferSize != null ? bufferSize : bufferSizeDefault);
+ return asThis();
+ }
+
+ /**
+ * 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.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param bufferSizeDefault the buffer size, null resets to the default.
+ * @return this.
+ */
+ protected B setBufferSizeDefault(final int bufferSizeDefault) {
+ this.bufferSizeDefault = bufferSizeDefault;
+ return asThis();
+ }
+
+ /**
+ * 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.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param charset the Charset, null resets to the default.
+ * @return this.
+ */
+ public B setCharset(final Charset charset) {
+ this.charset = Charsets.toCharset(charset, charsetDefault);
+ return asThis();
+ }
+
+ /**
+ * Sets the Charset.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param charset the Charset name, null resets to the default.
+ * @return this.
+ */
+ public B setCharset(final String charset) {
+ return setCharset(Charsets.toCharset(charset, charsetDefault));
+ }
+
+ /**
+ * Sets the Charset default for subclasses to initialize.
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param defaultCharset the Charset name, null resets to the default.
+ * @return this.
+ */
+ protected B setCharsetDefault(final Charset defaultCharset) {
+ this.charsetDefault = defaultCharset;
+ return asThis();
+ }
+
+ /**
+ * Sets the OpenOption[].
+ *
+ * Normally used with InputStream, OutputStream, and Writer.
+ *
+ *
+ * Subclasses may ignore this setting.
+ *
+ *
+ * @param openOptions the OpenOption[] name, null resets to the default.
+ * @return this.
+ * @since 2.13.0
+ * @see #setInputStream(InputStream)
+ * @see #setOutputStream(OutputStream)
+ * @see #setWriter(Writer)
+ */
+ public B setOpenOptions(final OpenOption... openOptions) {
+ 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));
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractSupplier.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractSupplier.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/build/AbstractSupplier.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,41 @@
+/*
+ * 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 org.apache.commons.io.function.IOSupplier;
+
+/**
+ * Abstracts supplying an instance of {@code T}. Use to implement the builder pattern.
+ *
+ * @param the type of instances to build.
+ * @param the type of builder subclass.
+ * @since 2.12.0
+ */
+public abstract class AbstractSupplier> implements IOSupplier {
+
+ /**
+ * Returns this instance typed as the proper subclass type.
+ *
+ * @return this instance typed as the proper subclass type.
+ */
+ @SuppressWarnings("unchecked")
+ protected B asThis() {
+ return (B) this;
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/build/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/build/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/build/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides classes to implement IO builders.
+ *
+ * @since 2.12.0
+ */
+package org.apache.commons.io.build;
Index: 3rdParty_sources/commons-io/org/apache/commons/io/channels/FileChannels.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/channels/FileChannels.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/channels/FileChannels.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,87 @@
+/*
+ * 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.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Objects;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * Works with {@link FileChannel}.
+ *
+ * @since 2.15.0
+ */
+public final class FileChannels {
+
+ /**
+ * Tests if two RandomAccessFiles contents are equal.
+ *
+ * @param channel1 A FileChannel.
+ * @param channel2 Another FileChannel.
+ * @param byteBufferSize The two internal buffer capacities, in bytes.
+ * @return true if the contents of both RandomAccessFiles are equal, false otherwise.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static boolean contentEquals(final FileChannel channel1, final FileChannel channel2, final int byteBufferSize) throws IOException {
+ // Short-circuit test
+ if (Objects.equals(channel1, channel2)) {
+ return true;
+ }
+ // Short-circuit test
+ final long size1 = size(channel1);
+ final long size2 = size(channel2);
+ if (size1 != size2) {
+ return false;
+ }
+ if (size1 == 0 && size2 == 0) {
+ return true;
+ }
+ // Dig in and do the work
+ final ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(byteBufferSize);
+ final ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(byteBufferSize);
+ while (true) {
+ final int read1 = channel1.read(byteBuffer1);
+ final int read2 = channel2.read(byteBuffer2);
+ byteBuffer1.clear();
+ byteBuffer2.clear();
+ if (read1 == IOUtils.EOF && read2 == IOUtils.EOF) {
+ return byteBuffer1.equals(byteBuffer2);
+ }
+ if (read1 != read2) {
+ return false;
+ }
+ if (!byteBuffer1.equals(byteBuffer2)) {
+ return false;
+ }
+ }
+ }
+
+ private static long size(final FileChannel channel) throws IOException {
+ return channel != null ? channel.size() : 0;
+ }
+
+ /**
+ * Don't instantiate.
+ */
+ private FileChannels() {
+ // no-op
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/channels/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/channels/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/channels/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides classes to work with {@link java.nio.channels}.
+ *
+ * @since 2.15.0
+ */
+package org.apache.commons.io.channels;
Index: 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetDecoders.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetDecoders.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetDecoders.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,44 @@
+/*
+ * 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.charset;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+/**
+ * Works with {@link CharsetDecoder}.
+ *
+ * @since 2.12.0
+ */
+public final class CharsetDecoders {
+
+ /**
+ * Returns the given non-null CharsetDecoder or a new default CharsetDecoder.
+ *
+ * @param charsetDecoder The CharsetDecoder to test.
+ * @return the given non-null CharsetDecoder or a new default CharsetDecoder.
+ */
+ public static CharsetDecoder toCharsetDecoder(final CharsetDecoder charsetDecoder) {
+ return charsetDecoder != null ? charsetDecoder : Charset.defaultCharset().newDecoder();
+ }
+
+ /** No instances. */
+ private CharsetDecoders() {
+ // No instances.
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetEncoders.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetEncoders.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/charset/CharsetEncoders.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,58 @@
+/*
+ * 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.charset;
+
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.util.function.Supplier;
+
+/**
+ * Works with {@link CharsetEncoder}.
+ *
+ * @since 2.12.0
+ */
+public final class CharsetEncoders {
+
+ /**
+ * Returns the given non-null CharsetEncoder or a new default CharsetEncoder.
+ *
+ * @param charsetEncoder The CharsetEncoder to test.
+ * @return the given non-null CharsetEncoder or a new default CharsetEncoder.
+ */
+ public static CharsetEncoder toCharsetEncoder(final CharsetEncoder charsetEncoder) {
+ return toCharsetEncoder(charsetEncoder, () -> Charset.defaultCharset().newEncoder());
+ }
+
+ /**
+ * Returns the given non-null CharsetEncoder or a new default CharsetEncoder.
+ *
+ * @param charsetEncoder The CharsetEncoder to test.
+ * @param defaultSupplier The CharsetEncoder supplier to get when charsetEncoder is null.
+ * @return the given non-null CharsetEncoder or a new default CharsetEncoder.
+ * @since 2.13.0
+ */
+ public static CharsetEncoder toCharsetEncoder(final CharsetEncoder charsetEncoder, final Supplier defaultSupplier) {
+ return charsetEncoder != null ? charsetEncoder : defaultSupplier.get();
+ }
+
+ /** No instances. */
+ private CharsetEncoders() {
+ // No instances.
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/charset/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/charset/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/charset/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides classes to work with code from {@link java.nio.charset}.
+ *
+ * @since 2.12.0
+ */
+package org.apache.commons.io.charset;
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java (.../AbstractFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/AbstractFileComparator.java (.../AbstractFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,7 +18,6 @@
import java.io.File;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -30,13 +29,13 @@
abstract class AbstractFileComparator implements Comparator {
/**
- * Sort an array of files.
+ * Sorts an array of files.
*
* This method uses {@link Arrays#sort(Object[], Comparator)} and returns the original array.
*
*
- * @param files The files to sort, may be null
- * @return The sorted array
+ * @param files The files to sort, may be null.
+ * @return The sorted array.
* @since 2.0
*/
public File[] sort(final File... files) {
@@ -47,13 +46,13 @@
}
/**
- * Sort a List of files.
+ * Sorts a List of files.
*
- * This method uses {@link Collections#sort(List, Comparator)} and returns the original list.
+ * This method uses {@link List#sort(Comparator)} and returns the original list.
*
*
- * @param files The files to sort, may be null
- * @return The sorted list
+ * @param files The files to sort, may be null.
+ * @return The sorted list.
* @since 2.0
*/
public List sort(final List files) {
@@ -66,7 +65,7 @@
/**
* String representation of this file comparator.
*
- * @return String representation of this file comparator
+ * @return String representation of this file comparator.
*/
@Override
public String toString() {
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java (.../CompositeFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/CompositeFileComparator.java (.../CompositeFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,89 +18,78 @@
import java.io.File;
import java.io.Serializable;
-import java.util.ArrayList;
import java.util.Comparator;
-import java.util.List;
+import java.util.function.IntFunction;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* Compare two files using a set of delegate file {@link Comparator}.
*
- * This comparator can be used to sort lists or arrays of files
- * by combining a number other comparators.
+ * This comparator can be used to sort lists or arrays of files by combining a number of other comparators.
*
- * Example of sorting a list of files by type (i.e. directory or file)
- * and then by name:
+ * Example of sorting a list of files by type (i.e. directory or file) and then by name:
+ *
*
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 2.0
*/
public class CompositeFileComparator extends AbstractFileComparator implements Serializable {
private static final Comparator>[] EMPTY_COMPARATOR_ARRAY = {};
private static final long serialVersionUID = -2224170307287243428L;
- private static final Comparator>[] NO_COMPARATORS = {};
+
+ /**
+ * Delegates.
+ */
private final Comparator[] delegates;
/**
- * Create a composite comparator for the set of delegate comparators.
+ * Constructs a composite comparator for the set of delegate comparators.
*
* @param delegates The delegate file comparators
*/
- @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct
- public CompositeFileComparator(final Comparator... delegates) {
- if (delegates == null) {
- this.delegates = (Comparator[]) NO_COMPARATORS;//1
- } else {
- this.delegates = (Comparator[]) new Comparator>[delegates.length];//2
- System.arraycopy(delegates, 0, this.delegates, 0, delegates.length);
- }
+ public CompositeFileComparator(@SuppressWarnings("unchecked") final Comparator... delegates) {
+ this.delegates = delegates == null ? emptyArray() : delegates.clone();
}
/**
- * Create a composite comparator for the set of delegate comparators.
+ * Constructs a composite comparator for the set of delegate comparators.
*
* @param delegates The delegate file comparators
*/
- @SuppressWarnings("unchecked") // casts 1 & 2 must be OK because types are already correct
public CompositeFileComparator(final Iterable> delegates) {
- if (delegates == null) {
- this.delegates = (Comparator[]) NO_COMPARATORS; //1
- } else {
- final List> list = new ArrayList<>();
- for (final Comparator comparator : delegates) {
- list.add(comparator);
- }
- this.delegates = (Comparator[]) list.toArray(EMPTY_COMPARATOR_ARRAY); //2
- }
+ this.delegates = delegates == null ? emptyArray()
+ : StreamSupport.stream(delegates.spliterator(), false).toArray((IntFunction[]>) Comparator[]::new);
}
/**
- * Compare the two files using delegate comparators.
+ * Compares the two files using delegate comparators.
*
* @param file1 The first file to compare
* @param file2 The second file to compare
- * @return the first non-zero result returned from
- * the delegate comparators or zero.
+ * @return the first non-zero result returned from the delegate comparators or zero.
*/
@Override
public int compare(final File file1, final File file2) {
- int result = 0;
- for (final Comparator delegate : delegates) {
- result = delegate.compare(file1, file2);
- if (result != 0) {
- break;
- }
- }
- return result;
+ return Stream.of(delegates).map(delegate -> delegate.compare(file1, file2)).filter(r -> r != 0).findFirst().orElse(0);
}
+ @SuppressWarnings("unchecked") // types are already correct
+ private Comparator[] emptyArray() {
+ return (Comparator[]) EMPTY_COMPARATOR_ARRAY;
+ }
+
/**
* String representation of this file comparator.
*
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java (.../DefaultFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DefaultFileComparator.java (.../DefaultFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -21,25 +21,31 @@
import java.util.Comparator;
/**
- * Compare two files using the default {@link File#compareTo(File)} method.
+ * Compares two files using the default {@link File#compareTo(File)} method.
*
* This comparator can be used to sort lists or arrays of files
* by using the default file comparison.
+ *
*
* Example of sorting a list of files using the
* {@link #DEFAULT_COMPARATOR} singleton instance:
+ *
*
* List<File> list = ...
* ((AbstractFileComparator) DefaultFileComparator.DEFAULT_COMPARATOR).sort(list);
*
*
* Example of doing a reverse sort of an array of files using the
* {@link #DEFAULT_REVERSE} singleton instance:
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.4
*/
@@ -54,7 +60,7 @@
public static final Comparator DEFAULT_REVERSE = new ReverseFileComparator(DEFAULT_COMPARATOR);
/**
- * Compare the two files using the {@link File#compareTo(File)} method.
+ * Compares the two files using the {@link File#compareTo(File)} method.
*
* @param file1 The first file to compare
* @param file2 The second file to compare
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java (.../DirectoryFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/DirectoryFileComparator.java (.../DirectoryFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,21 +24,28 @@
* Compare two files using the {@link File#isDirectory()} method.
*
* This comparator can be used to sort lists or arrays by directories and files.
+ *
*
- * Example of sorting a list of files/directories using the
- * {@link #DIRECTORY_COMPARATOR} singleton instance:
+ * Example of sorting a list of files/directories using the {@link #DIRECTORY_COMPARATOR} singleton instance:
+ *
+ *
*
* List<File> list = ...
* ((AbstractFileComparator) DirectoryFileComparator.DIRECTORY_COMPARATOR).sort(list);
*
*
- * Example of doing a reverse sort of an array of files/directories using the
- * {@link #DIRECTORY_REVERSE} singleton instance:
+ * Example of doing a reverse sort of an array of files/directories using the {@link #DIRECTORY_REVERSE}
+ * singleton instance:
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 2.0
*/
@@ -57,23 +64,22 @@
public static final Comparator DIRECTORY_REVERSE = new ReverseFileComparator(DIRECTORY_COMPARATOR);
/**
- * Compare the two files using the {@link File#isDirectory()} method.
+ * Compares the two files using the {@link File#isDirectory()} method.
*
- * @param file1 The first file to compare
- * @param file2 The second file to compare
- * @return the result of calling file1's
- * {@link File#compareTo(File)} with file2 as the parameter.
+ * @param file1 The first file to compare.
+ * @param file2 The second file to compare.
+ * @return the result of calling file1's {@link File#compareTo(File)} with file2 as the parameter.
*/
@Override
public int compare(final File file1, final File file2) {
return getType(file1) - getType(file2);
}
/**
- * Convert type to numeric value.
+ * Converts type to numeric value.
*
- * @param file The file
- * @return 1 for directories and 2 for files
+ * @param file The file.
+ * @return 1 for directories and 2 for files.
*/
private int getType(final File file) {
return file.isDirectory() ? TYPE_DIRECTORY : TYPE_FILE;
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java (.../ExtensionFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/ExtensionFileComparator.java (.../ExtensionFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -29,24 +29,30 @@
*
* This comparator can be used to sort lists or arrays of files
* by their file extension either in a case-sensitive, case-insensitive or
- * system dependent case sensitive way. A number of singleton instances
+ * system dependent case-sensitive way. A number of singleton instances
* are provided for the various case sensitivity options (using {@link IOCase})
* and the reverse of those options.
+ *
*
* Example of a case-sensitive file extension sort using the
* {@link #EXTENSION_COMPARATOR} singleton instance:
+ *
*
* List<File> list = ...
* ((AbstractFileComparator) ExtensionFileComparator.EXTENSION_COMPARATOR).sort(list);
*
*
* Example of a reverse case-insensitive file extension sort using the
* {@link #EXTENSION_INSENSITIVE_REVERSE} singleton instance:
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.4
*/
@@ -57,7 +63,7 @@
public static final Comparator LASTMODIFIED_REVERSE = new ReverseFileComparator(LASTMODIFIED_COMPARATOR);
/**
- * Compares the last the last modified date/time of two files.
+ * Compares the last modified date/time of two files.
*
* @param file1 The first file to compare.
* @param file2 The second file to compare.
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java (.../NameFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/NameFileComparator.java (.../NameFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -27,24 +27,30 @@
*
* This comparator can be used to sort lists or arrays of files
* by their name either in a case-sensitive, case-insensitive or
- * system dependent case sensitive way. A number of singleton instances
+ * system dependent case-sensitive way. A number of singleton instances
* are provided for the various case sensitivity options (using {@link IOCase})
* and the reverse of those options.
+ *
*
* Example of a case-sensitive file name sort using the
* {@link #NAME_COMPARATOR} singleton instance:
+ *
*
* List<File> list = ...
* ((AbstractFileComparator) NameFileComparator.NAME_COMPARATOR).sort(list);
*
*
* Example of a reverse case-insensitive file name sort using the
* {@link #NAME_INSENSITIVE_REVERSE} singleton instance:
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.4
*/
@@ -70,27 +76,27 @@
/** Reverse system sensitive name comparator instance (see {@link IOCase#SYSTEM}) */
public static final Comparator NAME_SYSTEM_REVERSE = new ReverseFileComparator(NAME_SYSTEM_COMPARATOR);
- /** Whether the comparison is case sensitive. */
- private final IOCase caseSensitivity;
+ /** Whether the comparison is case-sensitive. */
+ private final IOCase ioCase;
/**
- * Construct a case sensitive file name comparator instance.
+ * Constructs a case-sensitive file name comparator instance.
*/
public NameFileComparator() {
- this.caseSensitivity = IOCase.SENSITIVE;
+ this.ioCase = IOCase.SENSITIVE;
}
/**
- * Construct a file name comparator instance with the specified case-sensitivity.
+ * Constructs a file name comparator instance with the specified case-sensitivity.
*
- * @param caseSensitivity how to handle case sensitivity, null means case-sensitive
+ * @param ioCase how to handle case sensitivity, null means case-sensitive
*/
- public NameFileComparator(final IOCase caseSensitivity) {
- this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+ public NameFileComparator(final IOCase ioCase) {
+ this.ioCase = IOCase.value(ioCase, IOCase.SENSITIVE);
}
/**
- * Compare the names of two files with the specified case sensitivity.
+ * Compares the names of two files with the specified case sensitivity.
*
* @param file1 The first file to compare
* @param file2 The second file to compare
@@ -101,7 +107,7 @@
*/
@Override
public int compare(final File file1, final File file2) {
- return caseSensitivity.checkCompareTo(file1.getName(), file2.getName());
+ return ioCase.checkCompareTo(file1.getName(), file2.getName());
}
/**
@@ -111,6 +117,6 @@
*/
@Override
public String toString() {
- return super.toString() + "[caseSensitivity=" + caseSensitivity + "]";
+ return super.toString() + "[ioCase=" + ioCase + "]";
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java (.../PathFileComparator.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/PathFileComparator.java (.../PathFileComparator.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -27,25 +27,30 @@
*
* This comparator can be used to sort lists or arrays of files
* by their path either in a case-sensitive, case-insensitive or
- * system dependent case sensitive way. A number of singleton instances
+ * system dependent case-sensitive way. A number of singleton instances
* are provided for the various case sensitivity options (using {@link IOCase})
* and the reverse of those options.
+ *
*
* Example of a case-sensitive file path sort using the
* {@link #PATH_COMPARATOR} singleton instance:
+ *
*
* List<File> list = ...
* ((AbstractFileComparator) PathFileComparator.PATH_COMPARATOR).sort(list);
*
*
* Example of a reverse case-insensitive file path sort using the
* {@link #PATH_INSENSITIVE_REVERSE} singleton instance:
+ *
* N.B. Directories are treated as zero size unless
* {@code sumDirectoryContents} is {@code true}.
+ *
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.4
*/
@@ -74,18 +82,19 @@
private final boolean sumDirectoryContents;
/**
- * Construct a file size comparator instance (directories treated as zero size).
+ * Constructs a file size comparator instance (directories treated as zero size).
*/
public SizeFileComparator() {
this.sumDirectoryContents = false;
}
/**
- * Construct a file size comparator instance specifying whether the size of
+ * Constructs a file size comparator instance specifying whether the size of
* the directory contents should be aggregated.
*
* If the {@code sumDirectoryContents} is {@code true} The size of
* directories is calculated using {@link FileUtils#sizeOfDirectory(File)}.
+ *
*
* @param sumDirectoryContents {@code true} if the sum of the directories' contents
* should be calculated, otherwise {@code false} if directories should be treated
@@ -96,7 +105,7 @@
}
/**
- * Compare the length of two files.
+ * Compares the length of two files.
*
* @param file1 The first file to compare
* @param file2 The second file to compare
Index: 3rdParty_sources/commons-io/org/apache/commons/io/comparator/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/comparator/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/comparator/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides various {@link java.util.Comparator} implementations
+ * for {@link java.io.File}s and {@link java.nio.file.Path}.
+ *
Sorting
+ *
+ * All the comparators include convenience utility sort(File...) and
+ * sort(List) methods.
+ *
+ *
+ * For example, to sort the files in a directory by name:
+ *
SIZE_COMPARATOR
+ * - Compare using File.length() method (directories treated as zero length).
+ *
+ *
LASTMODIFIED_REVERSE
+ * - Reverse compare of File.length() method (directories treated as zero length).
+ *
+ *
SIZE_SUMDIR_COMPARATOR
+ * - Compare using FileUtils.sizeOfDirectory(File) method
+ * (sums the size of a directory's contents).
+ *
+ *
SIZE_SUMDIR_REVERSE
+ * - Reverse compare of FileUtils.sizeOfDirectory(File) method
+ * (sums the size of a directory's contents).
+ *
+ *
+ *
+ *
+ */
+package org.apache.commons.io.comparator;
Fisheye: Tag b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1 refers to a dead (removed) revision in file `3rdParty_sources/commons-io/org/apache/commons/io/comparator/package.html'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/AccumulatorPathVisitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/AccumulatorPathVisitor.java (.../AccumulatorPathVisitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/AccumulatorPathVisitor.java (.../AccumulatorPathVisitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,6 +18,7 @@
package org.apache.commons.io.file;
import java.io.IOException;
+import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
@@ -26,6 +27,7 @@
import java.util.Objects;
import org.apache.commons.io.file.Counters.PathCounters;
+import org.apache.commons.io.function.IOBiFunction;
/**
* Accumulates normalized paths during visitation.
@@ -35,9 +37,9 @@
*
Example
*
*
- * Path dir = Paths.get("");
+ * Path dir = PathUtils.current();
* // We are interested in files older than one day
- * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * Instant cutoff = Instant.now().minus(Duration.ofDays(1));
* AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
* //
* // Walk one dir
@@ -59,7 +61,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}.
*
* @return a new instance configured with a BigInteger {@link PathCounters}.
*/
@@ -68,7 +70,7 @@
}
/**
- * 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.
@@ -81,7 +83,7 @@
}
/**
- * 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}.
*/
@@ -90,7 +92,7 @@
}
/**
- * 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.
@@ -131,11 +133,24 @@
* @param dirFilter Filters which directories to count.
* @since 2.9.0
*/
- public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter,
- final PathFilter dirFilter) {
+ public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter) {
super(pathCounter, fileFilter, dirFilter);
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param pathCounter How to count path visits.
+ * @param fileFilter Filters which files to count.
+ * @param dirFilter Filters which directories to count.
+ * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}.
+ * @since 2.12.0
+ */
+ public AccumulatorPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter,
+ final IOBiFunction visitFileFailed) {
+ super(pathCounter, fileFilter, dirFilter, visitFileFailed);
+ }
+
private void add(final List list, final Path dir) {
list.add(dir.normalize());
}
@@ -156,21 +171,21 @@
}
/**
- * Gets the list of visited directories.
+ * Gets a copy of the list of visited directories.
*
- * @return the list of visited directories.
+ * @return a copy of the list of visited directories.
*/
public List getDirList() {
- return dirList;
+ return new ArrayList<>(dirList);
}
/**
- * Gets the list of visited files.
+ * Gets a copy of the list of visited files.
*
- * @return the list of visited files.
+ * @return a copy of the list of visited files.
*/
public List getFileList() {
- return fileList;
+ return new ArrayList<>(fileList);
}
@Override
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/CleaningPathVisitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/CleaningPathVisitor.java (.../CleaningPathVisitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/CleaningPathVisitor.java (.../CleaningPathVisitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -36,7 +36,7 @@
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 @@
}
/**
- * 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}.
*/
@@ -64,8 +64,7 @@
* @param skip The files to skip deleting.
* @since 2.8.0
*/
- public CleaningPathVisitor(final PathCounters pathCounter, final DeleteOption[] deleteOption,
- final String... skip) {
+ public CleaningPathVisitor(final PathCounters pathCounter, final DeleteOption[] deleteOption, final String... skip) {
super(pathCounter);
final String[] temp = skip != null ? skip.clone() : EMPTY_STRING_ARRAY;
Arrays.sort(temp);
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/CopyDirectoryVisitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/CopyDirectoryVisitor.java (.../CopyDirectoryVisitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/CopyDirectoryVisitor.java (.../CopyDirectoryVisitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -36,6 +36,10 @@
*/
public class CopyDirectoryVisitor extends CountingPathVisitor {
+ private static CopyOption[] toCopyOption(final CopyOption... copyOptions) {
+ return copyOptions == null ? PathUtils.EMPTY_COPY_OPTIONS : copyOptions.clone();
+ }
+
private final CopyOption[] copyOptions;
private final Path sourceDirectory;
private final Path targetDirectory;
@@ -48,12 +52,11 @@
* @param targetDirectory The target directory
* @param copyOptions Specifies how the copying should be done.
*/
- public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDirectory, final Path targetDirectory,
- final CopyOption... copyOptions) {
+ public CopyDirectoryVisitor(final PathCounters pathCounter, final Path sourceDirectory, final Path targetDirectory, final CopyOption... copyOptions) {
super(pathCounter);
this.sourceDirectory = sourceDirectory;
this.targetDirectory = targetDirectory;
- this.copyOptions = copyOptions == null ? PathUtils.EMPTY_COPY_OPTIONS : copyOptions.clone();
+ this.copyOptions = toCopyOption(copyOptions);
}
/**
@@ -67,12 +70,12 @@
* @param copyOptions Specifies how the copying should be done.
* @since 2.9.0
*/
- public CopyDirectoryVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter,
- final Path sourceDirectory, final Path targetDirectory, final CopyOption... copyOptions) {
+ public CopyDirectoryVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter, final Path sourceDirectory,
+ final Path targetDirectory, final CopyOption... copyOptions) {
super(pathCounter, fileFilter, dirFilter);
this.sourceDirectory = sourceDirectory;
this.targetDirectory = targetDirectory;
- this.copyOptions = copyOptions == null ? PathUtils.EMPTY_COPY_OPTIONS : copyOptions.clone();
+ this.copyOptions = toCopyOption(copyOptions);
}
/**
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/Counters.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/Counters.java (.../Counters.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/Counters.java (.../Counters.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -43,8 +43,7 @@
* @param directoryCounter the directory counter.
* @param fileCounter the file counter.
*/
- protected AbstractPathCounters(final Counter byteCounter, final Counter directoryCounter,
- final Counter fileCounter) {
+ protected AbstractPathCounters(final Counter byteCounter, final Counter directoryCounter, final Counter fileCounter) {
this.byteCounter = byteCounter;
this.directoryCounter = directoryCounter;
this.fileCounter = fileCounter;
@@ -105,7 +104,7 @@
}
/**
- * Counts using a BigInteger number.
+ * Counts using a {@link BigInteger} number.
*/
private static final class BigIntegerCounter implements Counter {
@@ -155,13 +154,13 @@
}
@Override
- public String toString() {
- return value.toString();
+ public void reset() {
+ value = BigInteger.ZERO;
}
@Override
- public void reset() {
- value = BigInteger.ZERO;
+ public String toString() {
+ return value.toString();
}
}
@@ -227,7 +226,7 @@
}
/**
- * Counts using a long number.
+ * Counts using a {@code long} number.
*/
private final static class LongCounter implements Counter {
@@ -277,13 +276,13 @@
}
@Override
- public String toString() {
- return Long.toString(value);
+ public void reset() {
+ value = 0L;
}
@Override
- public void reset() {
- value = 0L;
+ public String toString() {
+ return Long.toString(value);
}
}
@@ -333,6 +332,17 @@
// noop
}
+ /**
+ * Returns {@code "0"}, always.
+ *
+ * @return {@code "0"}, always.
+ * @since 2.12.0
+ */
+ @Override
+ public String toString() {
+ return "0";
+ }
+
}
/**
@@ -423,19 +433,19 @@
}
/**
- * Returns the NOOP Counter.
+ * Returns the no-op Counter.
*
- * @return the NOOP Counter.
+ * @return the no-op Counter.
* @since 2.9.0
*/
public static Counter noopCounter() {
return NoopCounter.INSTANCE;
}
/**
- * Returns the NOOP PathCounters.
+ * Returns the no-op PathCounters.
*
- * @return the NOOP PathCounters.
+ * @return the no-op PathCounters.
* @since 2.9.0
*/
public static PathCounters noopPathCounters() {
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/CountingPathVisitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/CountingPathVisitor.java (.../CountingPathVisitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/CountingPathVisitor.java (.../CountingPathVisitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -18,14 +18,18 @@
package org.apache.commons.io.file;
import java.io.IOException;
+import java.math.BigInteger;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;
import org.apache.commons.io.file.Counters.PathCounters;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.io.filefilter.SymbolicLinkFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
+import org.apache.commons.io.function.IOBiFunction;
/**
* Counts files, directories, and sizes, as a visit proceeds.
@@ -36,19 +40,27 @@
static final String[] EMPTY_STRING_ARRAY = {};
+ static IOFileFilter defaultDirFilter() {
+ return TrueFileFilter.INSTANCE;
+ }
+
+ static IOFileFilter defaultFileFilter() {
+ return new SymbolicLinkFileFilter(FileVisitResult.TERMINATE, FileVisitResult.CONTINUE);
+ }
+
/**
- * Creates a new instance configured with a BigInteger {@link PathCounters}.
+ * Constructs a new instance configured with a {@link BigInteger} {@link PathCounters}.
*
- * @return a new instance configured with a BigInteger {@link PathCounters}.
+ * @return a new instance configured with a {@link BigInteger} {@link PathCounters}.
*/
public static CountingPathVisitor withBigIntegerCounters() {
return new CountingPathVisitor(Counters.bigIntegerPathCounters());
}
/**
- * Creates a new instance configured with a long {@link PathCounters}.
+ * Constructs a new instance configured with a {@code long} {@link PathCounters}.
*
- * @return a new instance configured with a long {@link PathCounters}.
+ * @return a new instance configured with a {@code long} {@link PathCounters}.
*/
public static CountingPathVisitor withLongCounters() {
return new CountingPathVisitor(Counters.longPathCounters());
@@ -64,7 +76,7 @@
* @param pathCounter How to count path visits.
*/
public CountingPathVisitor(final PathCounters pathCounter) {
- this(pathCounter, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
+ this(pathCounter, defaultFileFilter(), defaultDirFilter());
}
/**
@@ -81,6 +93,23 @@
this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter");
}
+ /**
+ * Constructs a new instance.
+ *
+ * @param pathCounter How to count path visits.
+ * @param fileFilter Filters which files to count.
+ * @param dirFilter Filters which directories to count.
+ * @param visitFileFailed Called on {@link #visitFileFailed(Path, IOException)}.
+ * @since 2.12.0
+ */
+ public CountingPathVisitor(final PathCounters pathCounter, final PathFilter fileFilter, final PathFilter dirFilter,
+ final IOBiFunction visitFileFailed) {
+ super(visitFileFailed);
+ this.pathCounters = Objects.requireNonNull(pathCounter, "pathCounter");
+ this.fileFilter = Objects.requireNonNull(fileFilter, "fileFilter");
+ this.dirFilter = Objects.requireNonNull(dirFilter, "dirFilter");
+ }
+
@Override
public boolean equals(final Object obj) {
if (this == obj) {
@@ -148,6 +177,7 @@
@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attributes) throws IOException {
+ // Note: A file can be a symbolic link to a directory.
if (Files.exists(file) && fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE) {
updateFileCounters(file, attributes);
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/DeletingPathVisitor.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/DeletingPathVisitor.java (.../DeletingPathVisitor.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/DeletingPathVisitor.java (.../DeletingPathVisitor.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -37,7 +37,7 @@
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 @@
}
/**
- * 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}.
*/
@@ -66,9 +66,8 @@
* @param skip The files to skip deleting.
* @since 2.8.0
*/
- public DeletingPathVisitor(final PathCounters pathCounter, final DeleteOption[] deleteOption,
- final String... skip) {
- this(pathCounter, PathUtils.NOFOLLOW_LINK_OPTION_ARRAY, deleteOption, skip);
+ public DeletingPathVisitor(final PathCounters pathCounter, final DeleteOption[] deleteOption, final String... skip) {
+ this(pathCounter, PathUtils.noFollowLinkOptionArray(), deleteOption, skip);
}
/**
@@ -80,15 +79,14 @@
* @param skip The files to skip deleting.
* @since 2.9.0
*/
- public DeletingPathVisitor(final PathCounters pathCounter, final LinkOption[] linkOptions,
- final DeleteOption[] deleteOption, final String... skip) {
+ public DeletingPathVisitor(final PathCounters pathCounter, final LinkOption[] linkOptions, final DeleteOption[] deleteOption, final String... skip) {
super(pathCounter);
final String[] temp = skip != null ? skip.clone() : EMPTY_STRING_ARRAY;
Arrays.sort(temp);
this.skip = temp;
this.overrideReadOnly = StandardDeleteOption.overrideReadOnly(deleteOption);
// TODO Files.deleteIfExists() never follows links, so use LinkOption.NOFOLLOW_LINKS in other calls to Files.
- this.linkOptions = linkOptions == null ? PathUtils.NOFOLLOW_LINK_OPTION_ARRAY : linkOptions.clone();
+ this.linkOptions = linkOptions == null ? PathUtils.noFollowLinkOptionArray() : linkOptions.clone();
}
/**
@@ -165,7 +163,7 @@
try {
// deleteIfExists does not work for this case
Files.delete(file);
- } catch (final NoSuchFileException e) {
+ } catch (final NoSuchFileException ignored) {
// ignore
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/DirectoryStreamFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/DirectoryStreamFilter.java (.../DirectoryStreamFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/DirectoryStreamFilter.java (.../DirectoryStreamFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -48,7 +48,7 @@
@Override
public boolean accept(final Path path) throws IOException {
- return pathFilter.accept(path, PathUtils.readBasicFileAttributes(path)) == FileVisitResult.CONTINUE;
+ return pathFilter.accept(path, PathUtils.readBasicFileAttributes(path, PathUtils.EMPTY_LINK_OPTION_ARRAY)) == FileVisitResult.CONTINUE;
}
/**
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/FilesUncheck.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/FilesUncheck.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/FilesUncheck.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,809 @@
+/*
+ * 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.file;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.file.CopyOption;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileStore;
+import java.nio.file.FileVisitOption;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFilePermission;
+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;
+
+/**
+ * Delegates to {@link Files} to uncheck calls by throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @see Files
+ * @see IOException
+ * @see UncheckedIOException
+ * @since 2.12.0
+ */
+public final class FilesUncheck {
+
+ /**
+ * Delegates to {@link Files#copy(InputStream, Path, CopyOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param in See delegate.
+ * @param target See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ * @see Files#copy(InputStream, Path,CopyOption...)
+ */
+ public static long copy(final InputStream in, final Path target, final CopyOption... options) {
+ return Uncheck.apply(Files::copy, in, target, options);
+ }
+
+ /**
+ * Delegates to {@link Files#copy(Path, OutputStream)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param source See delegate. See delegate.
+ * @param out See delegate. See delegate.
+ * @return See delegate. See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static long copy(final Path source, final OutputStream out) {
+ return Uncheck.apply(Files::copy, source, out);
+ }
+
+ /**
+ * Delegates to {@link Files#copy(Path, Path, CopyOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param source See delegate.
+ * @param target See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path copy(final Path source, final Path target, final CopyOption... options) {
+ return Uncheck.apply(Files::copy, source, target, options);
+ }
+
+ /**
+ * Delegates to {@link Files#createDirectories(Path, FileAttribute...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param dir See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createDirectories(final Path dir, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createDirectories, dir, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createDirectory(Path, FileAttribute...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param dir See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createDirectory(final Path dir, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createDirectory, dir, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createFile(Path, FileAttribute...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createFile(final Path path, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createFile, path, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createLink(Path, Path)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param link See delegate.
+ * @param existing See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createLink(final Path link, final Path existing) {
+ return Uncheck.apply(Files::createLink, link, existing);
+ }
+
+ /**
+ * Delegates to {@link Files#createSymbolicLink(Path, Path, FileAttribute...)} throwing {@link UncheckedIOException}
+ * instead of {@link IOException}.
+ *
+ * @param link See delegate.
+ * @param target See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createSymbolicLink(final Path link, final Path target, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createSymbolicLink, link, target, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createTempDirectory(Path, String, FileAttribute...)} throwing {@link UncheckedIOException}
+ * instead of {@link IOException}.
+ *
+ * @param dir See delegate.
+ * @param prefix See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createTempDirectory(final Path dir, final String prefix, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createTempDirectory, dir, prefix, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createTempDirectory(String, FileAttribute...)} throwing {@link UncheckedIOException}
+ * instead of {@link IOException}.
+ *
+ * @param prefix See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createTempDirectory(final String prefix, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createTempDirectory, prefix, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createTempFile(Path, String, String, FileAttribute...)} throwing
+ * {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @param dir See delegate.
+ * @param prefix See delegate.
+ * @param suffix See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createTempFile(final Path dir, final String prefix, final String suffix, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createTempFile, dir, prefix, suffix, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#createTempFile(String, String, FileAttribute...)} throwing {@link UncheckedIOException}
+ * instead of {@link IOException}.
+ *
+ * @param prefix See delegate.
+ * @param suffix See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path createTempFile(final String prefix, final String suffix, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::createTempFile, prefix, suffix, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#delete(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static void delete(final Path path) {
+ Uncheck.accept(Files::delete, path);
+ }
+
+ /**
+ * Delegates to {@link Files#deleteIfExists(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static boolean deleteIfExists(final Path path) {
+ return Uncheck.apply(Files::deleteIfExists, path);
+ }
+
+ /**
+ * Delegates to {@link Files#find(Path, int, BiPredicate, FileVisitOption...)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * The returned {@link Stream} wraps a {@link DirectoryStream}. When you require timely disposal of file system resources, use a {@code try}-with-resources
+ * block to ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed.
+ *
+ *
+ * @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 find(final Path start, final int maxDepth, final BiPredicate 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}.
+ *
+ * @param path See delegate.
+ * @param attribute See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Object getAttribute(final Path path, final String attribute, final LinkOption... options) {
+ return Uncheck.apply(Files::getAttribute, path, attribute, options);
+ }
+
+ /**
+ * Delegates to {@link Files#getFileStore(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static FileStore getFileStore(final Path path) {
+ return Uncheck.apply(Files::getFileStore, path);
+ }
+
+ /**
+ * Delegates to {@link Files#getLastModifiedTime(Path, LinkOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static FileTime getLastModifiedTime(final Path path, final LinkOption... options) {
+ return Uncheck.apply(Files::getLastModifiedTime, path, options);
+ }
+
+ /**
+ * Delegates to {@link Files#getOwner(Path, LinkOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static UserPrincipal getOwner(final Path path, final LinkOption... options) {
+ return Uncheck.apply(Files::getOwner, path, options);
+ }
+
+ /**
+ * Delegates to {@link Files#getPosixFilePermissions(Path, LinkOption...)} throwing {@link UncheckedIOException} instead
+ * of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Set getPosixFilePermissions(final Path path, final LinkOption... options) {
+ return Uncheck.apply(Files::getPosixFilePermissions, path, options);
+ }
+
+ /**
+ * Delegates to {@link Files#isHidden(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static boolean isHidden(final Path path) {
+ return Uncheck.apply(Files::isHidden, path);
+ }
+
+ /**
+ * Delegates to {@link Files#isSameFile(Path, Path)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param path2 See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static boolean isSameFile(final Path path, final Path path2) {
+ return Uncheck.apply(Files::isSameFile, path, path2);
+ }
+
+ /**
+ * Delegates to {@link Files#lines(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * The returned {@link Stream} wraps a {@link Reader}. When you require timely disposal of file system resources, use a {@code try}-with-resources block to
+ * ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed.
+ *
+ *
+ * @param path See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Stream lines(final Path path) {
+ return Uncheck.apply(Files::lines, path);
+ }
+
+ /**
+ * Delegates to {@link Files#lines(Path, Charset)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * The returned {@link Stream} wraps a {@link Reader}. When you require timely disposal of file system resources, use a {@code try}-with-resources block to
+ * ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed.
+ *
+ *
+ * @param path See delegate.
+ * @param cs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Stream lines(final Path path, final Charset cs) {
+ return Uncheck.apply(Files::lines, path, cs);
+ }
+
+ /**
+ * Delegates to {@link Files#list(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * The returned {@link Stream} wraps a {@link DirectoryStream}. When you require timely disposal of file system resources, use a {@code try}-with-resources
+ * block to ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed.
+ *
+ *
+ * @param dir See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Stream list(final Path dir) {
+ return Uncheck.apply(Files::list, dir);
+ }
+
+ /**
+ * Delegates to {@link Files#move(Path, Path, CopyOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param source See delegate.
+ * @param target See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static Path move(final Path source, final Path target, final CopyOption... options) {
+ return Uncheck.apply(Files::move, source, target, options);
+ }
+
+ /**
+ * Delegates to {@link Files#newBufferedReader(Path)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static BufferedReader newBufferedReader(final Path path) {
+ return Uncheck.apply(Files::newBufferedReader, path);
+ }
+
+ /**
+ * Delegates to {@link Files#newBufferedReader(Path, Charset)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param cs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static BufferedReader newBufferedReader(final Path path, final Charset cs) {
+ return Uncheck.apply(Files::newBufferedReader, path, cs);
+ }
+
+ /**
+ * Delegates to {@link Files#newBufferedWriter(Path, Charset, OpenOption...)} throwing {@link UncheckedIOException}
+ * instead of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param cs See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static BufferedWriter newBufferedWriter(final Path path, final Charset cs, final OpenOption... options) {
+ return Uncheck.apply(Files::newBufferedWriter, path, cs, options);
+ }
+
+ /**
+ * Delegates to {@link Files#newBufferedWriter(Path, OpenOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static BufferedWriter newBufferedWriter(final Path path, final OpenOption... options) {
+ return Uncheck.apply(Files::newBufferedWriter, path, options);
+ }
+
+ /**
+ * Delegates to {@link Files#newByteChannel(Path, OpenOption...)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static SeekableByteChannel newByteChannel(final Path path, final OpenOption... options) {
+ return Uncheck.apply(Files::newByteChannel, path, options);
+ }
+
+ /**
+ * Delegates to {@link Files#newByteChannel(Path, Set, FileAttribute...)} throwing {@link UncheckedIOException} instead
+ * of {@link IOException}.
+ *
+ * @param path See delegate.
+ * @param options See delegate.
+ * @param attrs See delegate.
+ * @return See delegate.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ */
+ public static SeekableByteChannel newByteChannel(final Path path, final Set extends OpenOption> options, final FileAttribute>... attrs) {
+ return Uncheck.apply(Files::newByteChannel, path, options, attrs);
+ }
+
+ /**
+ * Delegates to {@link Files#newDirectoryStream(Path)} throwing {@link UncheckedIOException} instead of {@link IOException}.
+ *
+ * If you don't use the try-with-resources construct, then you must call the stream's {@link Stream#close()} method after iteration is complete to free any
+ * resources held for the open directory.
+ *
+ *
+ * @param dir See delegate.
+ * @return See delegate.
+ */
+ public static DirectoryStream newDirectoryStream(final Path dir) {
+ return Uncheck.apply(Files::newDirectoryStream, dir);
+ }
+
+ /**
+ * Delegates to {@link Files#newDirectoryStream(Path, java.nio.file.DirectoryStream.Filter)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * If you don't use the try-with-resources construct, then you must call the stream's {@link Stream#close()} method after iteration is complete to free any
+ * resources held for the open directory.
+ *
+ *
+ * @param dir See delegate.
+ * @param filter See delegate.
+ * @return See delegate.
+ */
+ public static DirectoryStream newDirectoryStream(final Path dir, final DirectoryStream.Filter super Path> filter) {
+ return Uncheck.apply(Files::newDirectoryStream, dir, filter);
+ }
+
+ /**
+ * Delegates to {@link Files#newDirectoryStream(Path, String)} throwing {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * The returned {@link Stream} wraps a {@link DirectoryStream}. When you require timely disposal of file system resources, use a {@code try}-with-resources
+ * block to ensure invocation of the stream's {@link Stream#close()} method after the stream operations are completed.
+ *
*
* @param filter the filter to apply to the set of files.
- * @param paths the array of files to apply the filter to.
+ * @param paths the array of files to apply the filter to.
*
* @return a subset of {@code files} that is accepted by the file filter.
- * @throws IllegalArgumentException if the filter is {@code null} or {@code files} contains a {@code null}
- * value.
+ * @throws NullPointerException if the filter is {@code null}
+ * @throws IllegalArgumentException if {@code files} contains a {@code null} value.
*
* @since 2.9.0
*/
@@ -688,8 +814,7 @@
return filterPaths(filter, Stream.of(paths), Collectors.toList()).toArray(EMPTY_PATH_ARRAY);
}
- private static R filterPaths(final PathFilter filter, final Stream stream,
- final Collector super Path, A, R> collector) {
+ private static R filterPaths(final PathFilter filter, final Stream stream, final Collector super Path, A, R> collector) {
Objects.requireNonNull(filter, "filter");
Objects.requireNonNull(collector, "collector");
if (stream == null) {
@@ -708,28 +833,147 @@
* Reads the access control list from a file attribute view.
*
* @param sourcePath the path to the file.
- * @return a file attribute view of the specified type, or null if the attribute view type is not available.
+ * @return a file attribute view of the given type, or null if the attribute view type is not available.
* @throws IOException if an I/O error occurs.
* @since 2.8.0
*/
public static List getAclEntryList(final Path sourcePath) throws IOException {
- final AclFileAttributeView fileAttributeView = Files.getFileAttributeView(sourcePath,
- AclFileAttributeView.class);
+ final AclFileAttributeView fileAttributeView = getAclFileAttributeView(sourcePath);
return fileAttributeView == null ? null : fileAttributeView.getAcl();
}
/**
- * Tests whether the specified {@code Path} is a directory or not. Implemented as a
- * null-safe delegate to {@code Files.isDirectory(Path path, LinkOption... options)}.
+ * Shorthand for {@code Files.getFileAttributeView(path, AclFileAttributeView.class)}.
*
- * @param path the path to the file.
- * @param options options indicating how symbolic links are handled
- * @return {@code true} if the file is a directory; {@code false} if
- * the path is null, the file does not exist, is not a directory, or it cannot
- * be determined if the file is a directory or not.
- * @throws SecurityException In the case of the default provider, and a security manager is installed, the
- * {@link SecurityManager#checkRead(String) checkRead} method is invoked to check read
- * access to the directory.
+ * @param path the path to the file.
+ * @param options how to handle symbolic links.
+ * @return a AclFileAttributeView, or {@code null} if the attribute view type is not available.
+ * @since 2.12.0
+ */
+ public static AclFileAttributeView getAclFileAttributeView(final Path path, final LinkOption... options) {
+ return Files.getFileAttributeView(path, AclFileAttributeView.class, options);
+ }
+
+ /**
+ * Shorthand for {@code Files.getFileAttributeView(path, DosFileAttributeView.class)}.
+ *
+ * @param path the path to the file.
+ * @param options how to handle symbolic links.
+ * @return a DosFileAttributeView, or {@code null} if the attribute view type is not available.
+ * @since 2.12.0
+ */
+ public static DosFileAttributeView getDosFileAttributeView(final Path path, final LinkOption... options) {
+ return Files.getFileAttributeView(path, DosFileAttributeView.class, options);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * The method provides a workaround for bug JDK-8177809 where {@link File#lastModified()}
+ * looses milliseconds and always ends in 000. This bug is in OpenJDK 8 and 9, and fixed in 11.
+ *
+ *
+ * @param file the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final File file) throws IOException {
+ return getLastModifiedFileTime(file.toPath(), null, EMPTY_LINK_OPTION_ARRAY);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param path the file to query.
+ * @param defaultIfAbsent Returns this file time of the file does not exist, may be null.
+ * @param options options indicating how symbolic links are handled.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final Path path, final FileTime defaultIfAbsent, final LinkOption... options) throws IOException {
+ return Files.exists(path) ? getLastModifiedTime(path, options) : defaultIfAbsent;
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param path the file to query.
+ * @param options options indicating how symbolic links are handled.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final Path path, final LinkOption... options) throws IOException {
+ return getLastModifiedFileTime(path, null, options);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param uri the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final URI uri) throws IOException {
+ return getLastModifiedFileTime(Paths.get(uri), null, EMPTY_LINK_OPTION_ARRAY);
+ }
+
+ /**
+ * Gets the file's last modified time or null if the file does not exist.
+ *
+ * @param url the file to query.
+ * @return the file's last modified time.
+ * @throws IOException Thrown if an I/O error occurs.
+ * @throws URISyntaxException if the URL is not formatted strictly according to RFC2396 and cannot be converted to a URI.
+ * @since 2.12.0
+ */
+ public static FileTime getLastModifiedFileTime(final URL url) throws IOException, URISyntaxException {
+ return getLastModifiedFileTime(url.toURI());
+ }
+
+ private static FileTime getLastModifiedTime(final Path path, final LinkOption... options) throws IOException {
+ return Files.getLastModifiedTime(Objects.requireNonNull(path, "path"), options);
+ }
+
+ private static Path getParent(final Path path) {
+ return path == null ? null : path.getParent();
+ }
+
+ /**
+ * Shorthand for {@code Files.getFileAttributeView(path, PosixFileAttributeView.class)}.
+ *
+ * @param path the path to the file.
+ * @param options how to handle symbolic links.
+ * @return a PosixFileAttributeView, or {@code null} if the attribute view type is not available.
+ * @since 2.12.0
+ */
+ public static PosixFileAttributeView getPosixFileAttributeView(final Path path, final LinkOption... options) {
+ return Files.getFileAttributeView(path, PosixFileAttributeView.class, options);
+ }
+
+ /**
+ * Gets a {@link Path} representing the system temporary directory.
+ *
+ * @return the system temporary directory.
+ * @since 2.12.0
+ */
+ public static Path getTempDirectory() {
+ return Paths.get(FileUtils.getTempDirectoryPath());
+ }
+
+ /**
+ * Tests whether the given {@link Path} is a directory or not. Implemented as a null-safe delegate to
+ * {@code Files.isDirectory(Path path, LinkOption... options)}.
+ *
+ * @param path the path to the file.
+ * @param options options indicating how to handle symbolic links
+ * @return {@code true} if the file is a directory; {@code false} if the path is null, the file does not exist, is not a directory, or it cannot be
+ * determined if the file is a directory or not.
+ * @throws SecurityException In the case of the default provider, and a security manager is installed, the {@link SecurityManager#checkRead(String)
+ * checkRead} method is invoked to check read access to the directory.
* @since 2.9.0
*/
public static boolean isDirectory(final Path path, final LinkOption... options) {
@@ -752,12 +996,10 @@
*
* @param directory the directory to query.
* @return whether the directory is empty.
- * @throws NotDirectoryException if the file could not otherwise be opened because it is not a directory
- * (optional specific exception).
+ * @throws NotDirectoryException if the file could not otherwise be opened because it is not a directory (optional specific exception).
* @throws IOException if an I/O error occurs.
- * @throws SecurityException In the case of the default provider, and a security manager is installed, the
- * {@link SecurityManager#checkRead(String) checkRead} method is invoked to check read
- * access to the directory.
+ * @throws SecurityException In the case of the default provider, and a security manager is installed, the {@link SecurityManager#checkRead(String)
+ * checkRead} method is invoked to check read access to the directory.
*/
public static boolean isEmptyDirectory(final Path directory) throws IOException {
try (DirectoryStream directoryStream = Files.newDirectoryStream(directory)) {
@@ -771,47 +1013,173 @@
* @param file the file to query.
* @return whether the file is empty.
* @throws IOException if an I/O error occurs.
- * @throws SecurityException In the case of the default provider, and a security manager is installed, its
- * {@link SecurityManager#checkRead(String) checkRead} method denies read access to the
- * file.
+ * @throws SecurityException In the case of the default provider, and a security manager is installed, its {@link SecurityManager#checkRead(String)
+ * checkRead} method denies read access to the file.
*/
public static boolean isEmptyFile(final Path file) throws IOException {
return Files.size(file) <= 0;
}
/**
- * Tests if the specified {@code Path} is newer than the specified time reference.
+ * Tests if the given {@link Path} is newer than the given time reference.
*
- * @param file the {@code Path} of which the modification date must be compared
+ * @param file the {@link Path} to test.
+ * @param czdt the time reference.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified after the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isNewer(final Path file, final ChronoZonedDateTime> czdt, final LinkOption... options) throws IOException {
+ Objects.requireNonNull(czdt, "czdt");
+ return isNewer(file, czdt.toInstant(), options);
+ }
+
+ /**
+ * Tests if the given {@link Path} is newer than the given time reference.
+ *
+ * @param file the {@link Path} to test.
+ * @param fileTime the time reference.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified after the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isNewer(final Path file, final FileTime fileTime, final LinkOption... options) throws IOException {
+ if (notExists(file)) {
+ return false;
+ }
+ return compareLastModifiedTimeTo(file, fileTime, options) > 0;
+ }
+
+ /**
+ * Tests if the given {@link Path} is newer than the given time reference.
+ *
+ * @param file the {@link Path} to test.
+ * @param instant the time reference.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified after the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isNewer(final Path file, final Instant instant, final LinkOption... options) throws IOException {
+ return isNewer(file, FileTime.from(instant), options);
+ }
+
+ /**
+ * Tests if the given {@link Path} is newer than the given time reference.
+ *
+ * @param file the {@link Path} to test.
* @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970)
- * @param options options indicating how symbolic links are handled * @return true if the {@code Path} exists and
- * has been modified after the given time reference.
- * @return true if the {@code Path} exists and has been modified after the given time reference.
- * @throws IOException if an I/O error occurs.
- * @throws NullPointerException if the file is {@code null}
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified after the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
* @since 2.9.0
*/
- public static boolean isNewer(final Path file, final long timeMillis, final LinkOption... options)
- throws IOException {
- Objects.requireNonNull(file, "file");
- if (Files.notExists(file)) {
+ public static boolean isNewer(final Path file, final long timeMillis, final LinkOption... options) throws IOException {
+ return isNewer(file, FileTime.fromMillis(timeMillis), options);
+ }
+
+ /**
+ * Tests if the given {@link Path} is newer than the reference {@link Path}.
+ *
+ * @param file the {@link File} to test.
+ * @param reference the {@link File} of which the modification date is used.
+ * @return true if the {@link File} exists and has been modified more recently than the reference {@link File}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static boolean isNewer(final Path file, final Path reference) throws IOException {
+ return isNewer(file, getLastModifiedTime(reference));
+ }
+
+ /**
+ * Tests if the given {@link Path} is older than the given time reference.
+ *
+ * @param file the {@link Path} to test.
+ * @param fileTime the time reference.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified before the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isOlder(final Path file, final FileTime fileTime, final LinkOption... options) throws IOException {
+ if (notExists(file)) {
return false;
}
- return Files.getLastModifiedTime(file, options).toMillis() > timeMillis;
+ return compareLastModifiedTimeTo(file, fileTime, options) < 0;
}
/**
- * Tests whether the specified {@code Path} is a regular file or not. Implemented as a
- * null-safe delegate to {@code Files.isRegularFile(Path path, LinkOption... options)}.
+ * Tests if the given {@link Path} is older than the given time reference.
*
- * @param path the path to the file.
- * @param options options indicating how symbolic links are handled
- * @return {@code true} if the file is a regular file; {@code false} if
- * the path is null, the file does not exist, is not a directory, or it cannot
- * be determined if the file is a regular file or not.
- * @throws SecurityException In the case of the default provider, and a security manager is installed, the
- * {@link SecurityManager#checkRead(String) checkRead} method is invoked to check read
- * access to the directory.
+ * @param file the {@link Path} to test.
+ * @param instant the time reference.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified before the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isOlder(final Path file, final Instant instant, final LinkOption... options) throws IOException {
+ return isOlder(file, FileTime.from(instant), options);
+ }
+
+ /**
+ * Tests if the given {@link Path} is older than the given time reference.
+ *
+ * @param file the {@link Path} to test.
+ * @param timeMillis the time reference measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970)
+ * @param options options indicating how to handle symbolic links.
+ * @return true if the {@link Path} exists and has been modified before the given time reference.
+ * @throws IOException if an I/O error occurs.
+ * @throws NullPointerException if the file is {@code null}.
+ * @since 2.12.0
+ */
+ public static boolean isOlder(final Path file, final long timeMillis, final LinkOption... options) throws IOException {
+ return isOlder(file, FileTime.fromMillis(timeMillis), options);
+ }
+
+ /**
+ * Tests if the given {@link Path} is older than the reference {@link Path}.
+ *
+ * @param file the {@link File} to test.
+ * @param reference the {@link File} of which the modification date is used.
+ * @return true if the {@link File} exists and has been modified before than the reference {@link File}.
+ * @throws IOException if an I/O error occurs.
+ * @since 2.12.0
+ */
+ public static boolean isOlder(final Path file, final Path reference) throws IOException {
+ return isOlder(file, getLastModifiedTime(reference));
+ }
+
+ /**
+ * Tests whether the given path is on a POSIX file system.
+ *
+ * @param test The Path to test.
+ * @param options options indicating how to handle symbolic links.
+ * @return true if test is on a POSIX file system.
+ * @since 2.12.0
+ */
+ public static boolean isPosix(final Path test, final LinkOption... options) {
+ return exists(test, options) && readPosixFileAttributes(test, options) != null;
+ }
+
+ /**
+ * Tests whether the given {@link Path} is a regular file or not. Implemented as a null-safe delegate to
+ * {@code Files.isRegularFile(Path path, LinkOption... options)}.
+ *
+ * @param path the path to the file.
+ * @param options options indicating how to handle symbolic links.
+ * @return {@code true} if the file is a regular file; {@code false} if the path is null, the file does not exist, is not a directory, or it cannot be
+ * determined if the file is a regular file or not.
+ * @throws SecurityException In the case of the default provider, and a security manager is installed, the {@link SecurityManager#checkRead(String)
+ * checkRead} method is invoked to check read access to the directory.
* @since 2.9.0
*/
public static boolean isRegularFile(final Path path, final LinkOption... options) {
@@ -820,18 +1188,57 @@
/**
* Creates a new DirectoryStream for Paths rooted at the given directory.
+ *
+ * If you don't use the try-with-resources construct, then you must call the stream's {@link Stream#close()} method after iteration is complete to free any
+ * resources held for the open directory.
+ *
+ * A file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00
+ * A.M. January 1, 1601 Coordinated Universal Time (UTC). This is the offset of Windows time 0 to Unix epoch in
+ * 100-nanosecond intervals.
+ *
+ */
+ static final long WINDOWS_EPOCH_OFFSET = -116444736000000000L;
+
+ /**
+ * The amount of 100-nanosecond intervals in one second.
+ */
+ private static final long HUNDRED_NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1) / 100;
+
+ /**
+ * The amount of 100-nanosecond intervals in one millisecond.
+ */
+ static final long HUNDRED_NANOS_PER_MILLISECOND = TimeUnit.MILLISECONDS.toNanos(1) / 100;
+
+ /**
+ * Subtracts milliseconds from a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param millisToSubtract The milliseconds to subtract.
+ * @return The resulting FileTime.
+ */
+ public static FileTime minusMillis(final FileTime fileTime, final long millisToSubtract) {
+ return FileTime.from(fileTime.toInstant().minusMillis(millisToSubtract));
+ }
+
+ /**
+ * Subtracts nanoseconds from a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param nanosToSubtract The nanoseconds to subtract.
+ * @return The resulting FileTime.
+ */
+ public static FileTime minusNanos(final FileTime fileTime, final long nanosToSubtract) {
+ return FileTime.from(fileTime.toInstant().minusNanos(nanosToSubtract));
+ }
+
+ /**
+ * Subtracts seconds from a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param secondsToSubtract The seconds to subtract.
+ * @return The resulting FileTime.
+ */
+ public static FileTime minusSeconds(final FileTime fileTime, final long secondsToSubtract) {
+ return FileTime.from(fileTime.toInstant().minusSeconds(secondsToSubtract));
+ }
+
+ /**
+ * Obtains the current instant FileTime from the system clock.
+ *
+ * @return the current instant FileTime from the system clock.
+ */
+ public static FileTime now() {
+ return FileTime.from(Instant.now());
+ }
+
+ /**
+ * Converts NTFS time (100 nanosecond units since 1 January 1601) to Java time.
+ *
+ * @param ntfsTime the NTFS time in 100 nanosecond units
+ * @return the Date
+ */
+ public static Date ntfsTimeToDate(final long ntfsTime) {
+ final long javaHundredNanos = Math.addExact(ntfsTime, WINDOWS_EPOCH_OFFSET);
+ final long javaMillis = Math.floorDiv(javaHundredNanos, HUNDRED_NANOS_PER_MILLISECOND);
+ return new Date(javaMillis);
+ }
+
+ /**
+ * Converts NTFS time (100-nanosecond units since 1 January 1601) to a FileTime.
+ *
+ * @param ntfsTime the NTFS time in 100-nanosecond units
+ * @return the FileTime
+ *
+ * @see #toNtfsTime(FileTime)
+ */
+ public static FileTime ntfsTimeToFileTime(final long ntfsTime) {
+ final long javaHundredsNanos = Math.addExact(ntfsTime, WINDOWS_EPOCH_OFFSET);
+ final long javaSeconds = Math.floorDiv(javaHundredsNanos, HUNDRED_NANOS_PER_SECOND);
+ final long javaNanos = Math.floorMod(javaHundredsNanos, HUNDRED_NANOS_PER_SECOND) * 100;
+ return FileTime.from(Instant.ofEpochSecond(javaSeconds, javaNanos));
+ }
+
+ /**
+ * Adds milliseconds to a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param millisToAdd The milliseconds to add.
+ * @return The resulting FileTime.
+ */
+ public static FileTime plusMillis(final FileTime fileTime, final long millisToAdd) {
+ return FileTime.from(fileTime.toInstant().plusMillis(millisToAdd));
+ }
+
+ /**
+ * Adds nanoseconds from a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param nanosToSubtract The nanoseconds to subtract.
+ * @return The resulting FileTime.
+ */
+ public static FileTime plusNanos(final FileTime fileTime, final long nanosToSubtract) {
+ return FileTime.from(fileTime.toInstant().plusNanos(nanosToSubtract));
+ }
+
+ /**
+ * Adds seconds to a source FileTime.
+ *
+ * @param fileTime The source FileTime.
+ * @param secondsToAdd The seconds to add.
+ * @return The resulting FileTime.
+ */
+ public static FileTime plusSeconds(final FileTime fileTime, final long secondsToAdd) {
+ return FileTime.from(fileTime.toInstant().plusSeconds(secondsToAdd));
+ }
+
+ /**
+ * Sets the last modified time of the given file path to now.
+ *
+ * @param path The file path to set.
+ * @throws IOException if an I/O error occurs.
+ */
+ public static void setLastModifiedTime(final Path path) throws IOException {
+ Files.setLastModifiedTime(path, now());
+ }
+
+ /**
+ * Converts {@link FileTime} to a {@link Date}. If the provided FileTime is {@code null}, the returned Date is also
+ * {@code null}.
+ *
+ * @param fileTime the file time to be converted.
+ * @return a {@link Date} which corresponds to the supplied time, or {@code null} if the time is {@code null}.
+ * @see #toFileTime(Date)
+ */
+ public static Date toDate(final FileTime fileTime) {
+ return fileTime != null ? new Date(fileTime.toMillis()) : null;
+ }
+
+ /**
+ * Converts {@link Date} to a {@link FileTime}. If the provided Date is {@code null}, the returned FileTime is also
+ * {@code null}.
+ *
+ * @param date the date to be converted.
+ * @return a {@link FileTime} which corresponds to the supplied date, or {@code null} if the date is {@code null}.
+ * @see #toDate(FileTime)
+ */
+ public static FileTime toFileTime(final Date date) {
+ return date != null ? FileTime.fromMillis(date.getTime()) : null;
+ }
+
+ /**
+ * Converts a {@link Date} to NTFS time.
+ *
+ * @param date the Date
+ * @return the NTFS time
+ */
+ public static long toNtfsTime(final Date date) {
+ final long javaHundredNanos = date.getTime() * HUNDRED_NANOS_PER_MILLISECOND;
+ return Math.subtractExact(javaHundredNanos, WINDOWS_EPOCH_OFFSET);
+ }
+
+ /**
+ * Converts a {@link FileTime} to NTFS time (100-nanosecond units since 1 January 1601).
+ *
+ * @param fileTime the FileTime
+ * @return the NTFS time in 100-nanosecond units
+ */
+ public static long toNtfsTime(final FileTime fileTime) {
+ final Instant instant = fileTime.toInstant();
+ final long javaHundredNanos = instant.getEpochSecond() * HUNDRED_NANOS_PER_SECOND + instant.getNano() / 100;
+ return Math.subtractExact(javaHundredNanos, WINDOWS_EPOCH_OFFSET);
+ }
+
+ private FileTimes() {
+ // No instances.
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/attribute/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/attribute/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/attribute/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides help using {@link java.nio.file.attribute} types.
+ */
+package org.apache.commons.io.file.attribute;
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides extensions in the realm of {@link java.nio.file}.
+ */
+package org.apache.commons.io.file;
Fisheye: Tag b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1 refers to a dead (removed) revision in file `3rdParty_sources/commons-io/org/apache/commons/io/file/package.html'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/FileSystemProviders.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/FileSystemProviders.java (.../FileSystemProviders.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/FileSystemProviders.java (.../FileSystemProviders.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -22,15 +22,16 @@
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.spi.FileSystemProvider;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
- * Helps working with {@link FileSystemProvider}.
+ * Helps to work with {@link FileSystemProvider}.
*
* @since 2.9.0
*/
-public class FileSystemProviders {
+public class FileSystemProviders { // NOPMD Class will be final in 3.0.
private static final FileSystemProviders INSTALLED = new FileSystemProviders(FileSystemProvider.installedProviders());
@@ -61,7 +62,7 @@
* Might make public later.
*/
private FileSystemProviders(final List providers) {
- this.providers = providers;
+ this.providers = providers != null ? providers : Collections.emptyList();
}
/**
@@ -78,14 +79,7 @@
return FileSystems.getDefault().provider();
}
// Find provider.
- if (providers != null) {
- for (final FileSystemProvider provider : providers) {
- if (provider.getScheme().equalsIgnoreCase(scheme)) {
- return provider;
- }
- }
- }
- return null;
+ return providers.stream().filter(provider -> provider.getScheme().equalsIgnoreCase(scheme)).findFirst().orElse(null);
}
/**
Index: 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/package-info.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/package-info.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/file/spi/package-info.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides extensions in the realm of {@link java.nio.file.spi}.
+ *
+ * @since 2.9.0
+ */
+package org.apache.commons.io.file.spi;
Fisheye: Tag b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1 refers to a dead (removed) revision in file `3rdParty_sources/commons-io/org/apache/commons/io/file/spi/package.html'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java (.../AbstractFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AbstractFileFilter.java (.../AbstractFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -23,10 +23,12 @@
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.List;
import java.util.Objects;
import org.apache.commons.io.file.PathFilter;
import org.apache.commons.io.file.PathVisitor;
+import org.apache.commons.io.function.IOSupplier;
/**
* Abstracts the implementation of the {@link FileFilter} (IO), {@link FilenameFilter} (IO), {@link PathFilter} (NIO)
@@ -39,11 +41,40 @@
*/
public abstract class AbstractFileFilter implements IOFileFilter, PathVisitor {
- static FileVisitResult toFileVisitResult(final boolean accept, final Path path) {
+ static FileVisitResult toDefaultFileVisitResult(final boolean accept) {
return accept ? FileVisitResult.CONTINUE : FileVisitResult.TERMINATE;
}
/**
+ * What to do when this filter accepts.
+ */
+ private final FileVisitResult onAccept;
+
+ /**
+ * What to do when this filter rejects.
+ */
+ private final FileVisitResult onReject;
+
+ /**
+ * Constructs a new instance.
+ */
+ public AbstractFileFilter() {
+ this(FileVisitResult.CONTINUE, FileVisitResult.TERMINATE);
+ }
+
+ /**
+ * Constructs a new instance.
+ *
+ * @param onAccept What to do on acceptance.
+ * @param onReject What to do on rejection.
+ * @since 2.12.0.
+ */
+ protected AbstractFileFilter(final FileVisitResult onAccept, final FileVisitResult onReject) {
+ this.onAccept = onAccept;
+ this.onReject = onReject;
+ }
+
+ /**
* Checks to see if the File should be accepted by this filter.
*
* @param file the File to check
@@ -68,6 +99,32 @@
return accept(new File(dir, name));
}
+ void append(final List> list, final StringBuilder buffer) {
+ for (int i = 0; i < list.size(); i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(list.get(i));
+ }
+ }
+
+ void append(final Object[] array, final StringBuilder buffer) {
+ for (int i = 0; i < array.length; i++) {
+ if (i > 0) {
+ buffer.append(",");
+ }
+ buffer.append(array[i]);
+ }
+ }
+
+ FileVisitResult get(final IOSupplier supplier) {
+ try {
+ return supplier.get();
+ } catch (IOException e) {
+ return handle(e);
+ }
+ }
+
/**
* Handles exceptions caught while accepting.
*
@@ -90,6 +147,16 @@
}
/**
+ * Converts a boolean into a FileVisitResult.
+ *
+ * @param accept accepted or rejected.
+ * @return a FileVisitResult.
+ */
+ FileVisitResult toFileVisitResult(final boolean accept) {
+ return accept ? onAccept : onReject;
+ }
+
+ /**
* Provides a String representation of this file filter.
*
* @return a String representation
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java (.../AgeFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AgeFileFilter.java (.../AgeFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -17,11 +17,11 @@
package org.apache.commons.io.filefilter;
import java.io.File;
-import java.io.IOException;
import java.io.Serializable;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.time.Instant;
import java.util.Date;
import org.apache.commons.io.FileUtils;
@@ -34,9 +34,9 @@
*
*
Using Classic IO
*
- * Path dir = Paths.get("");
+ * Path dir = PathUtils.current();
* // We are interested in files older than one day
- * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * Instant cutoff = Instant.now().minus(Duration.ofDays(1));
* String[] files = dir.list(new AgeFileFilter(cutoff));
* for (String file : files) {
* System.out.println(file);
@@ -45,9 +45,9 @@
*
*
Using NIO
*
- * Path dir = Paths.get("");
+ * Path dir = PathUtils.current();
* // We are interested in files older than one day
- * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * Instant cutoff = Instant.now().minus(Duration.ofDays(1));
* AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
* //
* // Walk one dir
@@ -63,6 +63,10 @@
* System.out.println(visitor.getDirList());
* System.out.println(visitor.getFileList());
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @see FileFilterUtils#ageFileFilter(Date)
* @see FileFilterUtils#ageFileFilter(File)
@@ -80,7 +84,7 @@
private final boolean acceptOlder;
/** The cutoff time threshold measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970). */
- private final long cutoffMillis;
+ private final Instant cutoffInstant;
/**
* Constructs a new age file filter for files older than (at or before) a certain cutoff date.
@@ -99,7 +103,7 @@
* cutoff).
*/
public AgeFileFilter(final Date cutoffDate, final boolean acceptOlder) {
- this(cutoffDate.getTime(), acceptOlder);
+ this(cutoffDate.toInstant(), acceptOlder);
}
/**
@@ -125,13 +129,35 @@
}
/**
+ * Constructs a new age file filter for files equal to or older than a certain cutoff.
+ *
+ * @param cutoffInstant The cutoff time threshold since the epoch (00:00:00 GMT, January 1, 1970).
+ * @since 2.12.0
+ */
+ public AgeFileFilter(final Instant cutoffInstant) {
+ this(cutoffInstant, true);
+ }
+
+ /**
+ * Constructs a new age file filter for files on any one side of a certain cutoff.
+ *
+ * @param cutoffInstant The cutoff time threshold since the epoch (00:00:00 GMT, January 1, 1970).
+ * @param acceptOlder if true, older files (at or before the cutoff) are accepted, else newer ones (after the cutoff).
+ * @since 2.12.0
+ */
+ public AgeFileFilter(final Instant cutoffInstant, final boolean acceptOlder) {
+ this.acceptOlder = acceptOlder;
+ this.cutoffInstant = cutoffInstant;
+ }
+
+ /**
* Constructs a new age file filter for files equal to or older than a certain cutoff
*
* @param cutoffMillis The cutoff time threshold measured in milliseconds since the epoch (00:00:00 GMT, January 1,
* 1970).
*/
public AgeFileFilter(final long cutoffMillis) {
- this(cutoffMillis, true);
+ this(Instant.ofEpochMilli(cutoffMillis), true);
}
/**
@@ -143,8 +169,7 @@
* cutoff).
*/
public AgeFileFilter(final long cutoffMillis, final boolean acceptOlder) {
- this.acceptOlder = acceptOlder;
- this.cutoffMillis = cutoffMillis;
+ this(Instant.ofEpochMilli(cutoffMillis), acceptOlder);
}
/**
@@ -159,8 +184,7 @@
*/
@Override
public boolean accept(final File file) {
- final boolean newer = FileUtils.isFileNewer(file, cutoffMillis);
- return acceptOlder != newer;
+ return acceptOlder != FileUtils.isFileNewer(file, cutoffInstant);
}
/**
@@ -176,13 +200,7 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- final boolean newer;
- try {
- newer = PathUtils.isNewer(file, cutoffMillis);
- } catch (final IOException e) {
- return handle(e);
- }
- return toFileVisitResult(acceptOlder != newer, file);
+ return get(() -> toFileVisitResult(acceptOlder != PathUtils.isNewer(file, cutoffInstant)));
}
/**
@@ -193,6 +211,6 @@
@Override
public String toString() {
final String condition = acceptOlder ? "<=" : ">";
- return super.toString() + "(" + condition + cutoffMillis + ")";
+ return super.toString() + "(" + condition + cutoffInstant + ")";
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java (.../AndFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/AndFileFilter.java (.../AndFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -25,13 +25,18 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.stream.Stream;
/**
* A {@link java.io.FileFilter} providing conditional AND logic across a list of
* file filters. This filter returns {@code true} if all filters in the
* list return {@code true}. Otherwise, it returns {@code false}.
* Checking of the file filter list stops when the first filter returns
* {@code false}.
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.0
* @see FileFilterUtils#and(IOFileFilter...)
@@ -73,6 +78,17 @@
}
/**
+ * Constructs a new instance for the give filters.
+ * @param fileFilters filters to OR.
+ *
+ * @since 2.9.0
+ */
+ public AndFileFilter(final IOFileFilter... fileFilters) {
+ this(Objects.requireNonNull(fileFilters, "fileFilters").length);
+ addFileFilter(fileFilters);
+ }
+
+ /**
* Constructs a new file filter that ANDs the result of other filters.
*
* @param filter1 the first filter, must second be null
@@ -86,18 +102,7 @@
}
/**
- * Constructs a new instance for the give filters.
- * @param fileFilters filters to OR.
- *
- * @since 2.9.0
- */
- public AndFileFilter(final IOFileFilter... fileFilters) {
- this(Objects.requireNonNull(fileFilters, "fileFilters").length);
- addFileFilter(fileFilters);
- }
-
- /**
- * Constructs a new instance of {@code AndFileFilter}
+ * Constructs a new instance of {@link AndFileFilter}
* with the specified list of filters.
*
* @param fileFilters a List of IOFileFilter instances, copied.
@@ -112,31 +117,15 @@
*/
@Override
public boolean accept(final File file) {
- if (isEmpty()) {
- return false;
- }
- for (final IOFileFilter fileFilter : fileFilters) {
- if (!fileFilter.accept(file)) {
- return false;
- }
- }
- return true;
+ return !isEmpty() && fileFilters.stream().allMatch(fileFilter -> fileFilter.accept(file));
}
/**
* {@inheritDoc}
*/
@Override
public boolean accept(final File file, final String name) {
- if (isEmpty()) {
- return false;
- }
- for (final IOFileFilter fileFilter : fileFilters) {
- if (!fileFilter.accept(file, name)) {
- return false;
- }
- }
- return true;
+ return !isEmpty() && fileFilters.stream().allMatch(fileFilter -> fileFilter.accept(file, name));
}
/**
@@ -145,15 +134,8 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- if (isEmpty()) {
- return FileVisitResult.TERMINATE;
- }
- for (final IOFileFilter fileFilter : fileFilters) {
- if (fileFilter.accept(file, attributes) != FileVisitResult.CONTINUE) {
- return FileVisitResult.TERMINATE;
- }
- }
- return FileVisitResult.CONTINUE;
+ return isEmpty() ? FileVisitResult.TERMINATE
+ : toDefaultFileVisitResult(fileFilters.stream().allMatch(fileFilter -> fileFilter.accept(file, attributes) == FileVisitResult.CONTINUE));
}
/**
@@ -171,9 +153,7 @@
* @since 2.9.0
*/
public void addFileFilter(final IOFileFilter... fileFilters) {
- for (final IOFileFilter fileFilter : Objects.requireNonNull(fileFilters, "fileFilters")) {
- addFileFilter(fileFilter);
- }
+ Stream.of(Objects.requireNonNull(fileFilters, "fileFilters")).forEach(this::addFileFilter);
}
/**
@@ -215,12 +195,7 @@
final StringBuilder buffer = new StringBuilder();
buffer.append(super.toString());
buffer.append("(");
- for (int i = 0; i < fileFilters.size(); i++) {
- if (i > 0) {
- buffer.append(",");
- }
- buffer.append(fileFilters.get(i));
- }
+ append(fileFilters, buffer);
buffer.append(")");
return buffer.toString();
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanExecuteFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanExecuteFileFilter.java (.../CanExecuteFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanExecuteFileFilter.java (.../CanExecuteFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,14 +24,14 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@code File}s that can be executed.
+ * This filter accepts {@link File}s that can be executed.
*
* Example, showing how to print out a list of the
* current directory's executable files:
*
*
Using Classic IO
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanExecuteFileFilter.CAN_EXECUTE);
* for (String file : files) {
* System.out.println(file);
@@ -44,12 +44,16 @@
*
*
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanExecuteFileFilter.CANNOT_EXECUTE);
* for (int i = 0; i < files.length; i++) {
* System.out.println(files[i]);
* }
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 2.7
*/
@@ -90,7 +94,7 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- return toFileVisitResult(Files.isExecutable(file), file);
+ return toFileVisitResult(Files.isExecutable(file));
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java (.../CanReadFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanReadFileFilter.java (.../CanReadFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,13 +24,13 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@code File}s that can be read.
+ * This filter accepts {@link File}s that can be read.
*
* Example, showing how to print out a list of the current directory's readable files:
*
*
Using Classic IO
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanReadFileFilter.CAN_READ);
* for (String file : files) {
* System.out.println(file);
@@ -41,7 +41,7 @@
* Example, showing how to print out a list of the current directory's un-readable files:
*
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanReadFileFilter.CANNOT_READ);
* for (String file : files) {
* System.out.println(file);
@@ -52,12 +52,16 @@
* Example, showing how to print out a list of the current directory's read-only files:
*
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanReadFileFilter.READ_ONLY);
* for (String file : files) {
* System.out.println(file);
* }
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.3
*/
@@ -100,7 +104,7 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- return toFileVisitResult(Files.isReadable(file), file);
+ return toFileVisitResult(Files.isReadable(file));
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java (.../CanWriteFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/CanWriteFileFilter.java (.../CanWriteFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,32 +24,35 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@code File}s that can be written to.
+ * This filter accepts {@link File}s that can be written to.
*
* Example, showing how to print out a list of the current directory's writable files:
*
*
Using Classic IO
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanWriteFileFilter.CAN_WRITE);
* for (String file : files) {
* System.out.println(file);
* }
*
- *
*
* Example, showing how to print out a list of the current directory's un-writable files:
- *
+ *
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(CanWriteFileFilter.CANNOT_WRITE);
* for (String file : files) {
* System.out.println(file);
* }
*
- *
*
* N.B. For read-only files, use {@code CanReadFileFilter.READ_ONLY}.
+ *
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.3
*/
@@ -89,7 +92,7 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- return toFileVisitResult(Files.isWritable(file), file);
+ return toFileVisitResult(Files.isWritable(file));
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java (.../DelegateFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DelegateFileFilter.java (.../DelegateFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -20,9 +20,14 @@
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.Serializable;
+import java.util.Objects;
/**
* This class turns a Java FileFilter or FilenameFilter into an IO FileFilter.
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.0
* @see FileFilterUtils#asFileFilter(FileFilter)
@@ -31,34 +36,31 @@
public class DelegateFileFilter extends AbstractFileFilter implements Serializable {
private static final long serialVersionUID = -8723373124984771318L;
+
/** The File filter */
- private final FileFilter fileFilter;
+ private transient final FileFilter fileFilter;
/** The Filename filter */
- private final FilenameFilter filenameFilter;
+ private transient final FilenameFilter fileNameFilter;
/**
* Constructs a delegate file filter around an existing FileFilter.
*
- * @param filter the filter to decorate
+ * @param fileFilter the filter to decorate
*/
- public DelegateFileFilter(final FileFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("The FileFilter must not be null");
- }
- this.fileFilter = filter;
- this.filenameFilter = null;
+ public DelegateFileFilter(final FileFilter fileFilter) {
+ Objects.requireNonNull(fileFilter, "filter");
+ this.fileFilter = fileFilter;
+ this.fileNameFilter = null;
}
/**
* Constructs a delegate file filter around an existing FilenameFilter.
*
- * @param filter the filter to decorate
+ * @param fileNameFilter the filter to decorate
*/
- public DelegateFileFilter(final FilenameFilter filter) {
- if (filter == null) {
- throw new IllegalArgumentException("The FilenameFilter must not be null");
- }
- this.filenameFilter = filter;
+ public DelegateFileFilter(final FilenameFilter fileNameFilter) {
+ Objects.requireNonNull(fileNameFilter, "filter");
+ this.fileNameFilter = fileNameFilter;
this.fileFilter = null;
}
@@ -85,8 +87,8 @@
*/
@Override
public boolean accept(final File dir, final String name) {
- if (filenameFilter != null) {
- return filenameFilter.accept(dir, name);
+ if (fileNameFilter != null) {
+ return fileNameFilter.accept(dir, name);
}
return super.accept(dir, name);
}
@@ -98,7 +100,7 @@
*/
@Override
public String toString() {
- final String delegate = fileFilter != null ? fileFilter.toString() : filenameFilter.toString();
+ final String delegate = fileFilter != null ? fileFilter.toString() : fileNameFilter.toString();
return super.toString() + "(" + delegate + ")";
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java (.../DirectoryFileFilter.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/DirectoryFileFilter.java (.../DirectoryFileFilter.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -24,14 +24,14 @@
import java.nio.file.attribute.BasicFileAttributes;
/**
- * This filter accepts {@code File}s that are directories.
+ * This filter accepts {@link File}s that are directories.
*
* For example, here is how to print out a list of the current directory's subdirectories:
*
*
Using Classic IO
*
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(DirectoryFileFilter.INSTANCE);
* for (String file : files) {
* System.out.println(file);
@@ -41,7 +41,7 @@
*
Using NIO
*
*
- * final Path dir = Paths.get("");
+ * final Path dir = PathUtils.current();
* final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(DirectoryFileFilter.INSTANCE);
* //
* // Walk one dir
@@ -57,6 +57,10 @@
* System.out.println(visitor.getDirList());
* System.out.println(visitor.getFileList());
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
- * If the {@code File} is a directory it checks that it contains no files.
+ * If the {@link File} is a directory it checks that it contains no files.
*
*
* Example, showing how to print out a list of the current directory's empty files/directories:
*
*
Using Classic IO
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(EmptyFileFilter.EMPTY);
* for (String file : files) {
* System.out.println(file);
@@ -49,7 +48,7 @@
*
*
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(EmptyFileFilter.NOT_EMPTY);
* for (String file : files) {
* System.out.println(file);
@@ -58,7 +57,7 @@
*
*
Using NIO
*
- * final Path dir = Paths.get("");
+ * final Path dir = PathUtils.current();
* final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(EmptyFileFilter.EMPTY);
* //
* // Walk one dir
@@ -74,6 +73,10 @@
* System.out.println(visitor.getDirList());
* System.out.println(visitor.getFileList());
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
* For example, here is how to print out a list of the real files
* within the current directory:
*
*
Using Classic IO
*
- * File dir = new File(".");
+ * File dir = FileUtils.current();
* String[] files = dir.list(FileFileFilter.INSTANCE);
* for (String file : files) {
* System.out.println(file);
@@ -40,7 +40,7 @@
*
*
Using NIO
*
- * final Path dir = Paths.get("");
+ * final Path dir = PathUtils.current();
* final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(FileFileFilter.INSTANCE);
* //
* // Walk one dir
@@ -56,6 +56,10 @@
* System.out.println(visitor.getDirList());
* System.out.println(visitor.getFileList());
*
+ *
Deprecating Serialization
+ *
+ * Serialization is deprecated and will be removed in 3.0.
+ *
*
* @since 1.3
* @see FileFilterUtils#fileFileFilter()
@@ -105,7 +109,7 @@
*/
@Override
public FileVisitResult accept(final Path file, final BasicFileAttributes attributes) {
- return toFileVisitResult(Files.isRegularFile(file), file);
+ return toFileVisitResult(Files.isRegularFile(file));
}
}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java
===================================================================
diff -u -re98540848441375f30de49a3557a5c9b0e7bea99 -rb9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1
--- 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java (.../FileFilterUtils.java) (revision e98540848441375f30de49a3557a5c9b0e7bea99)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/filefilter/FileFilterUtils.java (.../FileFilterUtils.java) (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -19,7 +19,6 @@
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
@@ -36,7 +35,7 @@
import org.apache.commons.io.IOCase;
/**
- * Useful utilities for working with file filters. It provides access to all
+ * Useful utilities for working with file filters. It provides access to most
* file filter implementations in this package so you don't have to import
* every class you use.
*
@@ -45,12 +44,12 @@
public class FileFilterUtils {
/* Constructed on demand and then cached */
- private static final IOFileFilter cvsFilter = notFileFilter(
+ private static final IOFileFilter CVS_FILTER = notFileFilter(
and(directoryFileFilter(), nameFileFilter("CVS")));
/* Constructed on demand and then cached */
- private static final IOFileFilter svnFilter = notFileFilter(
+ private static final IOFileFilter SVN_FILTER = notFileFilter(
and(directoryFileFilter(), nameFileFilter(".svn")));
/**
@@ -111,26 +110,26 @@
* Returns a filter that returns true if the file was last modified before
* or at the specified cutoff time.
*
- * @param cutoff the time threshold
+ * @param cutoffMillis the time threshold
* @return an appropriately configured age file filter
* @see AgeFileFilter
* @since 1.2
*/
- public static IOFileFilter ageFileFilter(final long cutoff) {
- return new AgeFileFilter(cutoff);
+ public static IOFileFilter ageFileFilter(final long cutoffMillis) {
+ return new AgeFileFilter(cutoffMillis);
}
/**
* Returns a filter that filters files based on a cutoff time.
*
- * @param cutoff the time threshold
+ * @param cutoffMillis the time threshold
* @param acceptOlder if true, older files get accepted, if false, newer
* @return an appropriately configured age file filter
* @see AgeFileFilter
* @since 1.2
*/
- public static IOFileFilter ageFileFilter(final long cutoff, final boolean acceptOlder) {
- return new AgeFileFilter(cutoff, acceptOlder);
+ public static IOFileFilter ageFileFilter(final long cutoffMillis, final boolean acceptOlder) {
+ return new AgeFileFilter(cutoffMillis, acceptOlder);
}
/**
@@ -164,8 +163,8 @@
}
/**
- * Returns an {@code IOFileFilter} that wraps the
- * {@code FileFilter} instance.
+ * Returns an {@link IOFileFilter} that wraps the
+ * {@link FileFilter} instance.
*
* @param filter the filter to be wrapped
* @return a new filter that implements IOFileFilter
@@ -176,8 +175,8 @@
}
/**
- * Returns an {@code IOFileFilter} that wraps the
- * {@code FilenameFilter} instance.
+ * Returns an {@link IOFileFilter} that wraps the
+ * {@link FilenameFilter} instance.
*
* @param filter the filter to be wrapped
* @return a new filter that implements IOFileFilter
@@ -234,15 +233,13 @@
*
* @return a subset of {@code files} that is accepted by the
* file filter.
- * @throws IllegalArgumentException if the filter is {@code null}
+ * @throws NullPointerException if the filter is {@code null}
* or {@code files} contains a {@code null} value.
*
* @since 2.0
*/
public static File[] filter(final IOFileFilter filter, final File... files) {
- if (filter == null) {
- throw new IllegalArgumentException("file filter is null");
- }
+ Objects.requireNonNull(filter, "filter");
if (files == null) {
return FileUtils.EMPTY_FILE_ARRAY;
}
@@ -251,33 +248,6 @@
/**
*
- * Applies an {@link IOFileFilter} to the provided {@link File} stream and collects the accepted files.
- *
These boolean FilenameFilters can be nested, to allow arbitrary expressions.
+ * For example, here is how one could print all non-directory files in the
+ * current directory, starting with "A", and ending in ".java" or ".class":
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list(
+ * new AndFileFilter(
+ * new AndFileFilter(
+ * new PrefixFileFilter("A"),
+ * new OrFileFilter(
+ * new SuffixFileFilter(".class"),
+ * new SuffixFileFilter(".java")
+ * )
+ * ),
+ * new NotFileFilter(
+ * new DirectoryFileFilter()
+ * )
+ * )
+ * );
+ * for (int i=0; i<files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
+ * You can alternatively build a filter tree using the "and", "or", and "not" methods on filters themselves:
+ *
+ *
+ * File dir = new File(".");
+ * String[] files = dir.list(
+ * new AndFileFilter(
+ * new PrefixFileFilter("A").and(
+ * new SuffixFileFilter(".class").or(new SuffixFileFilter(".java"))),
+ * new DirectoryFileFilter().not()
+ * )
+ * );
+ * for (int i=0; i<files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ *
+ *
This package also contains a utility class:
+ * FileFilterUtils. It allows you to use all
+ * file filters without having to put them in the import section. Here's how the
+ * above example will look using FileFilterUtils:
You can combine Java file tree walking by using java.nio.file.Files.walk() APIs with filters:
+ *
+ * final Path dir = Paths.get("");
+ * // We are interested in files older than one day
+ * final long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * final AccumulatorPathVisitor visitor = AccumulatorPathVisitor.withLongCounters(new AgeFileFilter(cutoff));
+ * //
+ * // Walk one dir
+ * Files.walkFileTree(dir, Collections.emptySet(), 1, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getFileList());
+ * //
+ * visitor.getPathCounters().reset();
+ * //
+ * // Walk dir tree
+ * Files.walkFileTree(dir, visitor);
+ * System.out.println(visitor.getPathCounters());
+ * System.out.println(visitor.getDirList());
+ * System.out.println(visitor.getFileList());
+ *
+ *
There are a few other goodies in that class so please have a look at the
+ * documentation in detail.
+ */
+package org.apache.commons.io.filefilter;
Fisheye: Tag b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1 refers to a dead (removed) revision in file `3rdParty_sources/commons-io/org/apache/commons/io/filefilter/package.html'.
Fisheye: No comparison available. Pass `N' to diff?
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/Constants.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/Constants.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/Constants.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+/**
+ * Defines package-private constants.
+ */
+final class Constants {
+
+ /**
+ * No-op singleton.
+ */
+ @SuppressWarnings("rawtypes")
+ static final IOBiConsumer IO_BI_CONSUMER = (t, u) -> {/* No-op */};
+
+ /**
+ * No-op singleton.
+ */
+ @SuppressWarnings("rawtypes")
+ static final IOBiFunction IO_BI_FUNCTION = (t, u) -> null;
+
+ /**
+ * No-op singleton.
+ */
+ @SuppressWarnings("rawtypes")
+ static final IOFunction IO_FUNCTION_ID = t -> t;
+
+ /**
+ * Always false.
+ */
+ static final IOPredicate IO_PREDICATE_FALSE = t -> false;
+
+ /**
+ * Always true.
+ */
+ static final IOPredicate IO_PREDICATE_TRUE = t -> true;
+
+ /**
+ * No-op singleton.
+ */
+ @SuppressWarnings("rawtypes")
+ static final IOTriConsumer IO_TRI_CONSUMER = (t, u, v) -> {/* No-op */};
+
+ private Constants() {
+ // We don't want instances
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/Erase.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/Erase.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/Erase.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,189 @@
+/*
+ * 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;
+
+/**
+ * Erases {@link IOException} for the compiler but still throws that exception at runtime.
+ */
+final class Erase {
+
+ /**
+ * Delegates to the given {@link IOBiConsumer} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param See delegate.
+ * @param consumer See delegate.
+ * @param t See delegate.
+ * @param u See delegate.
+ * @see IOBiConsumer
+ */
+ static void accept(final IOBiConsumer consumer, final T t, final U u) {
+ try {
+ consumer.accept(t, u);
+ } catch (final IOException ex) {
+ rethrow(ex); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOConsumer} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param consumer See delegate.
+ * @param t See delegate.
+ * @see IOConsumer
+ */
+ static void accept(final IOConsumer consumer, final T t) {
+ try {
+ consumer.accept(t);
+ } catch (final IOException ex) {
+ rethrow(ex); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOBiFunction} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param See delegate.
+ * @param See delegate.
+ * @param mapper See delegate.
+ * @param t See delegate.
+ * @param u See delegate.
+ * @return See delegate.
+ * @see IOBiFunction
+ */
+ static R apply(final IOBiFunction super T, ? super U, ? extends R> mapper, final T t, final U u) {
+ try {
+ return mapper.apply(t, u);
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOFunction} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param See delegate.
+ * @param mapper See delegate.
+ * @param t See delegate.
+ * @return See delegate.
+ * @see IOFunction
+ */
+ static R apply(final IOFunction super T, ? extends R> mapper, final T t) {
+ try {
+ return mapper.apply(t);
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOComparator} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param comparator See delegate.
+ * @param t See delegate.
+ * @param u See delegate.
+ * @return See delegate.
+ * @see IOComparator
+ */
+ static int compare(final IOComparator super T> comparator, final T t, final T u) {
+ try {
+ return comparator.compare(t, u);
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOSupplier} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param supplier See delegate.
+ * @return See delegate.
+ * @see IOSupplier
+ */
+ static T get(final IOSupplier supplier) {
+ try {
+ return supplier.get();
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /**
+ * Throws the given throwable.
+ *
+ * @param The throwable cast type.
+ * @param throwable The throwable to rethrow.
+ * @return nothing because we throw.
+ * @throws T Always thrown.
+ */
+ @SuppressWarnings("unchecked")
+ static RuntimeException rethrow(final Throwable throwable) throws T {
+ throw (T) throwable;
+ }
+
+ /**
+ * Delegates to the given {@link IORunnable} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param runnable See delegate.
+ * @see IORunnable
+ */
+ static void run(final IORunnable runnable) {
+ try {
+ runnable.run();
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /**
+ * Delegates to the given {@link IOPredicate} but erases its {@link IOException} for the compiler, while still throwing
+ * the exception at runtime.
+ *
+ * @param See delegate.
+ * @param predicate See delegate.
+ * @param t See delegate.
+ * @return See delegate.
+ * @see IOPredicate
+ */
+ static boolean test(final IOPredicate super T> predicate, final T t) {
+ try {
+ return predicate.test(t);
+ } catch (final IOException e) {
+ throw rethrow(e); // throws IOException
+ }
+ }
+
+ /** No instances. */
+ private Erase() {
+ // No instances.
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStream.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStream.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStream.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,154 @@
+/*
+ * 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.Closeable;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.stream.BaseStream;
+import java.util.stream.Stream;
+
+/**
+ * Like {@link BaseStream} but throws {@link IOException}.
+ *
+ * @param the type of the stream elements.
+ * @param the type of the IO stream extending {@code IOBaseStream}.
+ * @param the type of the stream extending {@code BaseStream}.
+ * @since 2.12.0
+ */
+public interface IOBaseStream, B extends BaseStream> extends Closeable {
+
+ /**
+ * Constructs a {@link BaseStream} for this instance that throws {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @return an {@link UncheckedIOException} {@link BaseStream}.
+ */
+ @SuppressWarnings("unchecked")
+ default BaseStream asBaseStream() {
+ return new UncheckedIOBaseStream<>((S) this);
+ }
+
+ /**
+ * Like {@link BaseStream#close()}.
+ *
+ * @see BaseStream#close()
+ */
+ @Override
+ default void close() {
+ unwrap().close();
+ }
+
+ /**
+ * Like {@link BaseStream#isParallel()}.
+ *
+ * @return See {@link BaseStream#isParallel() delegate}.
+ * @see BaseStream#isParallel()
+ */
+ @SuppressWarnings("resource") // for unwrap()
+ default boolean isParallel() {
+ return unwrap().isParallel();
+ }
+
+ /**
+ * Like {@link BaseStream#iterator()}.
+ *
+ * @return See {@link BaseStream#iterator() delegate}.
+ * @see BaseStream#iterator()
+ */
+ @SuppressWarnings("resource") // for unwrap()
+ default IOIterator iterator() {
+ return IOIteratorAdapter.adapt(unwrap().iterator());
+ }
+
+ /**
+ * Like {@link BaseStream#onClose(Runnable)}.
+ *
+ * @param closeHandler See {@link BaseStream#onClose(Runnable) delegate}.
+ * @return See {@link BaseStream#onClose(Runnable) delegate}.
+ * @throws IOException if an I/O error occurs.
+ * @see BaseStream#onClose(Runnable)
+ */
+ @SuppressWarnings({"unused", "resource"}) // throws IOException, unwrap()
+ default S onClose(final IORunnable closeHandler) throws IOException {
+ return wrap(unwrap().onClose(() -> Erase.run(closeHandler)));
+ }
+
+ /**
+ * Like {@link BaseStream#parallel()}.
+ *
+ * @return See {@link BaseStream#parallel() delegate}.
+ * @see BaseStream#parallel()
+ */
+ @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this
+ default S parallel() {
+ return isParallel() ? (S) this : wrap(unwrap().parallel());
+ }
+
+ /**
+ * Like {@link BaseStream#sequential()}.
+ *
+ * @return See {@link BaseStream#sequential() delegate}.
+ * @see BaseStream#sequential()
+ */
+ @SuppressWarnings({"resource", "unchecked"}) // for unwrap(), this
+ default S sequential() {
+ return isParallel() ? wrap(unwrap().sequential()) : (S) this;
+ }
+
+ /**
+ * Like {@link BaseStream#spliterator()}.
+ *
+ * @return See {@link BaseStream#spliterator() delegate}.
+ * @see BaseStream#spliterator()
+ */
+ @SuppressWarnings("resource") // for unwrap()
+ default IOSpliterator spliterator() {
+ return IOSpliteratorAdapter.adapt(unwrap().spliterator());
+ }
+
+ /**
+ * Like {@link BaseStream#unordered()}.
+ *
+ * @return See {@link BaseStream#unordered() delegate}.
+ * @see java.util.stream.BaseStream#unordered()
+ */
+ @SuppressWarnings("resource") // for unwrap()
+ default S unordered() {
+ return wrap(unwrap().unordered());
+ }
+
+ /**
+ * Unwraps this instance and returns the underlying {@link Stream}.
+ *
+ * Implementations may not have anything to unwrap and that behavior is undefined for now.
+ *
+ *
+ * @return the underlying stream.
+ */
+ B unwrap();
+
+ /**
+ * Wraps a {@link Stream}.
+ *
+ * @param delegate The delegate.
+ * @return An IO stream.
+ */
+ S wrap(B delegate);
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStreamAdapter.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStreamAdapter.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBaseStreamAdapter.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,52 @@
+/*
+ * 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.util.Objects;
+import java.util.stream.BaseStream;
+
+/**
+ * Abstracts an {@link IOBaseStream} implementation.
+ *
+ * Keep package-private for now.
+ *
+ * @param the type of the stream elements.
+ * @param the type of the stream extending {@code IOBaseStream}.
+ */
+abstract class IOBaseStreamAdapter, B extends BaseStream> implements IOBaseStream {
+
+ /**
+ * The underlying base stream.
+ */
+ private final B delegate;
+
+ /**
+ * Constructs an instance.
+ *
+ * @param delegate the delegate.
+ */
+ IOBaseStreamAdapter(final B delegate) {
+ this.delegate = Objects.requireNonNull(delegate, "delegate");
+ }
+
+ @Override
+ public B unwrap() {
+ return delegate;
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiConsumer.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiConsumer.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiConsumer.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,88 @@
+/*
+ * 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.Objects;
+import java.util.function.BiConsumer;
+
+/**
+ * Like {@link BiConsumer} but throws {@link IOException}.
+ *
+ * @param the type of the first argument to the operation
+ * @param the type of the second argument to the operation
+ *
+ * @see BiConsumer
+ * @since 2.12.0
+ */
+@FunctionalInterface
+public interface IOBiConsumer {
+
+ /**
+ * Returns the no-op singleton.
+ *
+ * @param the type of the first argument to the operation
+ * @param the type of the second argument to the operation
+ * @return The no-op singleton.
+ */
+ @SuppressWarnings("unchecked")
+ static IOBiConsumer noop() {
+ return Constants.IO_BI_CONSUMER;
+ }
+
+ /**
+ * Performs this operation on the given arguments.
+ *
+ * @param t the first input argument
+ * @param u the second input argument
+ * @throws IOException if an I/O error occurs.
+ */
+ void accept(T t, U u) throws IOException;
+
+ /**
+ * Creates a composed {@link IOBiConsumer} that performs, in sequence, this operation followed by the {@code after}
+ * operation. If performing either operation throws an exception, it is relayed to the caller of the composed operation.
+ * If performing this operation throws an exception, the {@code after} operation will not be performed.
+ *
+ * @param after the operation to perform after this operation
+ * @return a composed {@link IOBiConsumer} that performs in sequence this operation followed by the {@code after}
+ * operation
+ * @throws NullPointerException if {@code after} is null
+ */
+ default IOBiConsumer andThen(final IOBiConsumer super T, ? super U> after) {
+ Objects.requireNonNull(after);
+ return (t, u) -> {
+ accept(t, u);
+ after.accept(t, u);
+ };
+ }
+
+ /**
+ * Creates a {@link BiConsumer} for this instance that throws {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @return an UncheckedIOException BiConsumer.
+ * @throws UncheckedIOException Wraps an {@link IOException}.
+ * @since 2.12.0
+ */
+ default BiConsumer asBiConsumer() {
+ return (t, u) -> Uncheck.accept(this, t, u);
+ }
+
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiFunction.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiFunction.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBiFunction.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,78 @@
+/*
+ * 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.Objects;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Like {@link BiFunction} but throws {@link IOException}.
+ *
+ *
+ * This is a functional interface whose functional method is
+ * {@link #apply(Object, Object)}.
+ *
+ *
+ * @param the type of the first argument to the function
+ * @param the type of the second argument to the function
+ * @param the type of the result of the function
+ *
+ * @see Function
+ * @since 2.12.0
+ */
+@FunctionalInterface
+public interface IOBiFunction {
+
+ /**
+ * Creates a composed function that first applies this function to its input, and then applies the {@code after}
+ * function to the result. If evaluation of either function throws an exception, it is relayed to the caller of the
+ * composed function.
+ *
+ * @param the type of output of the {@code after} function, and of the composed function
+ * @param after the function to apply after this function is applied
+ * @return a composed function that first applies this function and then applies the {@code after} function
+ * @throws NullPointerException if after is null
+ */
+ default IOBiFunction andThen(final IOFunction super R, ? extends V> after) {
+ Objects.requireNonNull(after);
+ return (final T t, final U u) -> after.apply(apply(t, u));
+ }
+
+ /**
+ * Applies this function to the given arguments.
+ *
+ * @param t the first function argument
+ * @param u the second function argument
+ * @return the function result
+ * @throws IOException if an I/O error occurs.
+ */
+ R apply(T t, U u) throws IOException;
+
+ /**
+ * Creates a {@link BiFunction} for this instance that throws {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @return an UncheckedIOException BiFunction.
+ */
+ default BiFunction asBiFunction() {
+ return (t, u) -> Uncheck.apply(this, t, u);
+ }
+}
Index: 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBinaryOperator.java
===================================================================
diff -u
--- 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBinaryOperator.java (revision 0)
+++ 3rdParty_sources/commons-io/org/apache/commons/io/function/IOBinaryOperator.java (revision b9fa1c6ec0d498310eb2977544bd3cd9ae2b24d1)
@@ -0,0 +1,76 @@
+/*
+ * 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.Objects;
+import java.util.function.BinaryOperator;
+
+/**
+ * Like {@link BinaryOperator} but throws {@link IOException}.
+ *
+ * @param the type of the operands and result of the operator.
+ *
+ * @see IOBiFunction
+ * @see BinaryOperator
+ * @since 2.12.0
+ */
+@FunctionalInterface
+public interface IOBinaryOperator extends IOBiFunction {
+
+ /**
+ * Creates a {@link IOBinaryOperator} which returns the greater of two elements according to the specified
+ * {@code Comparator}.
+ *
+ * @param the type of the input arguments of the comparator
+ * @param comparator a {@code Comparator} for comparing the two values
+ * @return a {@code BinaryOperator} which returns the greater of its operands, according to the supplied
+ * {@code Comparator}
+ * @throws NullPointerException if the argument is null
+ */
+ static IOBinaryOperator maxBy(final IOComparator super T> comparator) {
+ Objects.requireNonNull(comparator);
+ return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
+ }
+
+ /**
+ * Creates a {@link IOBinaryOperator} which returns the lesser of two elements according to the specified
+ * {@code Comparator}.
+ *
+ * @param the type of the input arguments of the comparator
+ * @param comparator a {@code Comparator} for comparing the two values
+ * @return a {@code BinaryOperator} which returns the lesser of its operands, according to the supplied
+ * {@code Comparator}
+ * @throws NullPointerException if the argument is null
+ */
+ static IOBinaryOperator minBy(final IOComparator super T> comparator) {
+ Objects.requireNonNull(comparator);
+ return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
+ }
+
+ /**
+ * Creates a {@link BinaryOperator} for this instance that throws {@link UncheckedIOException} instead of
+ * {@link IOException}.
+ *
+ * @return an unchecked BiFunction.
+ */
+ default BinaryOperator