From e6165e551d879edc564e85ee1e656384dcd3cc6e Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 16 Aug 2020 15:22:29 +0000 Subject: [PATCH 1/9] Java 9: InputStream.transferTo(OutputStream) instead of JVM-based byte transferTo Provides potential higher performance. Signed-off-by: Markus KARG --- src/main/java/org/codehaus/plexus/util/IOUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index 3fab8411..0b2ae40b 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -156,7 +156,7 @@ private IOUtil() public static void copy( final InputStream input, final OutputStream output ) throws IOException { - copy( input, output, DEFAULT_BUFFER_SIZE ); + input.transferTo( output ); } /** From eebe1beaee69570f3d18a2e4acc7b6f13e88502a Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 16 Aug 2020 15:24:05 +0000 Subject: [PATCH 2/9] Java 10: Reader.transferTo(Writer) instead of JVM-based byte transfer Provides potential higher performance. Signed-off-by: Markus KARG --- src/main/java/org/codehaus/plexus/util/IOUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index 0b2ae40b..fdb64163 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -186,7 +186,7 @@ public static void copy( final InputStream input, final OutputStream output, fin public static void copy( final Reader input, final Writer output ) throws IOException { - copy( input, output, DEFAULT_BUFFER_SIZE ); + input.transferTo( output ); } /** From be51d3aa192a1aba27affbf0a05d8c956be10362 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Fri, 1 Jan 2021 15:19:11 +0000 Subject: [PATCH 3/9] Multi-Release-Jar Signed-off-by: Markus KARG --- pom.xml | 50 + .../java/org/codehaus/plexus/util/IOUtil.java | 4 +- .../org/codehaus/plexus/util/IOUtil.java | 886 ++++++++++++++++++ .../org/codehaus/plexus/util/IOUtil.java | 886 ++++++++++++++++++ 4 files changed, 1824 insertions(+), 2 deletions(-) create mode 100644 src/main/java10/org/codehaus/plexus/util/IOUtil.java create mode 100644 src/main/java9/org/codehaus/plexus/util/IOUtil.java diff --git a/pom.xml b/pom.xml index efad18f9..f34b6334 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,46 @@ limitations under the License. + + maven-compiler-plugin + + + default-compile + + compile + + + 8 + + + + compile-java-9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + compile-java-10 + + compile + + + 10 + + ${project.basedir}/src/main/java10 + + true + + + + org.apache.maven.plugins maven-scm-publish-plugin @@ -134,6 +174,16 @@ limitations under the License. + + maven-jar-plugin + + + + true + + + + diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index fdb64163..3fab8411 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -156,7 +156,7 @@ private IOUtil() public static void copy( final InputStream input, final OutputStream output ) throws IOException { - input.transferTo( output ); + copy( input, output, DEFAULT_BUFFER_SIZE ); } /** @@ -186,7 +186,7 @@ public static void copy( final InputStream input, final OutputStream output, fin public static void copy( final Reader input, final Writer output ) throws IOException { - input.transferTo( output ); + copy( input, output, DEFAULT_BUFFER_SIZE ); } /** diff --git a/src/main/java10/org/codehaus/plexus/util/IOUtil.java b/src/main/java10/org/codehaus/plexus/util/IOUtil.java new file mode 100644 index 00000000..fdb64163 --- /dev/null +++ b/src/main/java10/org/codehaus/plexus/util/IOUtil.java @@ -0,0 +1,886 @@ +package org.codehaus.plexus.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.codehaus.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Turbine" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact codehaus@codehaus.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache Turbine", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.channels.Channel; + +/** + * General IO Stream manipulation. + *

+ * This class provides static utility methods for input/output operations, particularly buffered copying between sources + * (InputStream, Reader, String and byte[]) and destinations + * (OutputStream, Writer, String and byte[]). + *

+ *

+ * Unless otherwise noted, these copy methods do not flush or close the streams. Often, doing so + * would require making non-portable assumptions about the streams' origin and further use. This means that both + * streams' close() methods must be called after copying. if one omits this step, then the stream resources + * (sockets, file descriptors) are released when the associated Stream is garbage-collected. It is not a good idea to + * rely on this mechanism. For a good overview of the distinction between "memory management" and "resource management", + * see this UnixReview article + *

+ *

+ * For each copy method, a variant is provided that allows the caller to specify the buffer size (the + * default is 4k). As the buffer size can have a fairly large impact on speed, this may be worth tweaking. Often "large + * buffer -> faster" does not hold, even for large data transfers. + *

+ *

+ * For byte-to-char methods, a copy variant allows the encoding to be selected (otherwise the platform + * default is used). + *

+ *

+ * The copy methods use an internal buffer when copying. It is therefore advisable not to + * deliberately wrap the stream arguments to the copy methods in Buffered* streams. For + * example, don't do the following: + *

+ * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); + *

+ * The rationale is as follows: + *

+ *

+ * Imagine that an InputStream's read() is a very expensive operation, which would usually suggest wrapping in a + * BufferedInputStream. The BufferedInputStream works by issuing infrequent + * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to fill an + * internal buffer, from which further read requests can inexpensively get their data (until the buffer + * runs out). + *

+ *

+ * However, the copy methods do the same thing, keeping an internal buffer, populated by + * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers (or three if the destination stream + * is also buffered) is pointless, and the unnecessary buffer management hurts performance slightly (about 3%, according + * to some simple experiments). + *

+ * + * @author Peter Donald + * @author Jeff Turner + * + * @since 4.0 + */ + +/* + * Behold, intrepid explorers; a map of this class: Method Input Output Dependency ------ ----- ------ ------- 1 copy + * InputStream OutputStream (primitive) 2 copy Reader Writer (primitive) 3 copy InputStream Writer 2 4 toString + * InputStream String 3 5 toByteArray InputStream byte[] 1 6 copy Reader OutputStream 2 7 toString Reader String 2 8 + * toByteArray Reader byte[] 6 9 copy String OutputStream 2 10 copy String Writer (trivial) 11 toByteArray String byte[] + * 9 12 copy byte[] Writer 3 13 toString byte[] String 12 14 copy byte[] OutputStream (trivial) Note that only the first + * two methods shuffle bytes; the rest use these two, or (if possible) copy using native Java copy methods. As there are + * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods. + */ + +public final class IOUtil +{ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; + + /** + * Private constructor to prevent instantiation. + */ + private IOUtil() + { + } + + /////////////////////////////////////////////////////////////// + // Core copy methods + /////////////////////////////////////////////////////////////// + + /** + * Copy bytes from an InputStream to an OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final InputStream input, final OutputStream output ) + throws IOException + { + input.transferTo( output ); + } + + /** + * Copy bytes from an InputStream to an OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final OutputStream output, final int bufferSize ) + throws IOException + { + final byte[] buffer = new byte[bufferSize]; + int n = 0; + while ( 0 <= ( n = input.read( buffer ) ) ) + { + output.write( buffer, 0, n ); + } + } + + /** + * Copy chars from a Reader to a Writer. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final Reader input, final Writer output ) + throws IOException + { + input.transferTo( output ); + } + + /** + * Copy chars from a Reader to a Writer. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final Reader input, final Writer output, final int bufferSize ) + throws IOException + { + final char[] buffer = new char[bufferSize]; + int n = 0; + while ( 0 <= ( n = input.read( buffer ) ) ) + { + output.write( buffer, 0, n ); + } + output.flush(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // InputStream -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // InputStream -> Writer + + /** + * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final int bufferSize ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input ); + copy( in, output, bufferSize ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final String encoding ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input, encoding ); + copy( in, output ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final String encoding, final int bufferSize ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input, encoding ); + copy( in, output, bufferSize ); + } + + /////////////////////////////////////////////////////////////// + // InputStream -> String + + /** + * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final InputStream input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /** + * @return Get the contents of an InputStream as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final String encoding ) + throws IOException + { + return toString( input, encoding, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final String encoding, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, encoding, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // InputStream -> byte[] + + /** + * @return Get the contents of an InputStream as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final InputStream input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final InputStream input, final int bufferSize ) + throws IOException + { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // Reader -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // Reader -> OutputStream + /** + * Serialize chars from a Reader to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final Reader input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a Reader to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final Reader input, final OutputStream output, final int bufferSize ) + throws IOException + { + final OutputStreamWriter out = new OutputStreamWriter( output ); + copy( input, out, bufferSize ); + // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush + // here. + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // Reader -> String + /** + * @return Get the contents of a Reader as a String. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final Reader input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a Reader as a String. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final Reader input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // Reader -> byte[] + /** + * @return Get the contents of a Reader as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final Reader input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a Reader as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final Reader input, final int bufferSize ) + throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // String -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // String -> OutputStream + + /** + * Serialize chars from a String to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final String input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a String to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final String input, final OutputStream output, final int bufferSize ) + throws IOException + { + final StringReader in = new StringReader( input ); + final OutputStreamWriter out = new OutputStreamWriter( output ); + copy( in, out, bufferSize ); + // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush + // here. + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // String -> Writer + + /** + * Copy chars from a String to a Writer. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final String input, final Writer output ) + throws IOException + { + output.write( input ); + } + + /** + * Copy bytes from an InputStream to an OutputStream, with buffering. This is equivalent + * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to + * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed + * after the copy. + * @param input to convert + * @param output the result + * @deprecated Buffering streams is actively harmful! See the class description as to why. Use + * {@link #copy(InputStream, OutputStream)} instead. + * @throws IOException io issue + */ + @Deprecated + public static void bufferedCopy( final InputStream input, final OutputStream output ) + throws IOException + { + final BufferedInputStream in = new BufferedInputStream( input ); + final BufferedOutputStream out = new BufferedOutputStream( output ); + copy( in, out ); + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // String -> byte[] + /** + * @return Get the contents of a String as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final String input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a String as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final String input, final int bufferSize ) + throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // byte[] -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // byte[] -> Writer + + /** + * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final int bufferSize ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, bufferSize ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final String encoding ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, encoding ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final String encoding, final int bufferSize ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, encoding, bufferSize ); + } + + /////////////////////////////////////////////////////////////// + // byte[] -> String + + /** + * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final byte[] input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final byte[] input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /** + * @return Get the contents of a byte[] as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static String toString( final byte[] input, final String encoding ) + throws IOException + { + return toString( input, encoding, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return the contents of a byte[] as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * + * @throws IOException io issue + */ + public static String toString( final byte[] input, final String encoding, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, encoding, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // byte[] -> OutputStream + + /** + * Copy bytes from a byte[] to an OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final byte[] input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy bytes from a byte[] to an OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final OutputStream output, final int bufferSize ) + throws IOException + { + output.write( input ); + } + + /** + * Compare the contents of two Streams to determine if they are equal or not. + * + * @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 IOException io issue + */ + public static boolean contentEquals( final InputStream input1, final InputStream input2 ) + throws IOException + { + final InputStream bufferedInput1 = new BufferedInputStream( input1 ); + final InputStream bufferedInput2 = new BufferedInputStream( input2 ); + + int ch = bufferedInput1.read(); + while ( 0 <= ch ) + { + final int ch2 = bufferedInput2.read(); + if ( ch != ch2 ) + { + return false; + } + ch = bufferedInput1.read(); + } + + final int ch2 = bufferedInput2.read(); + if ( 0 <= ch2 ) + { + return false; + } + else + { + return true; + } + } + + // ---------------------------------------------------------------------- + // closeXXX() + // ---------------------------------------------------------------------- + + /** + * Closes the input stream. The input stream can be null and any IOException's will be swallowed. + * + * @param inputStream The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( InputStream inputStream ) + { + if ( inputStream == null ) + { + return; + } + + try + { + inputStream.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes a channel. Channel can be null and any IOException's will be swallowed. + * + * @param channel The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Channel channel ) + { + if ( channel == null ) + { + return; + } + + try + { + channel.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the output stream. The output stream can be null and any IOException's will be swallowed. + * + * @param outputStream The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( OutputStream outputStream ) + { + if ( outputStream == null ) + { + return; + } + + try + { + outputStream.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the reader. The reader can be null and any IOException's will be swallowed. + * + * @param reader The reader to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Reader reader ) + { + if ( reader == null ) + { + return; + } + + try + { + reader.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the writer. The writer can be null and any IOException's will be swallowed. + * + * @param writer The writer to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Writer writer ) + { + if ( writer == null ) + { + return; + } + + try + { + writer.close(); + } + catch ( IOException ex ) + { + // ignore + } + } +} diff --git a/src/main/java9/org/codehaus/plexus/util/IOUtil.java b/src/main/java9/org/codehaus/plexus/util/IOUtil.java new file mode 100644 index 00000000..0b2ae40b --- /dev/null +++ b/src/main/java9/org/codehaus/plexus/util/IOUtil.java @@ -0,0 +1,886 @@ +package org.codehaus.plexus.util; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.codehaus.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache Turbine" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact codehaus@codehaus.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache Turbine", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.channels.Channel; + +/** + * General IO Stream manipulation. + *

+ * This class provides static utility methods for input/output operations, particularly buffered copying between sources + * (InputStream, Reader, String and byte[]) and destinations + * (OutputStream, Writer, String and byte[]). + *

+ *

+ * Unless otherwise noted, these copy methods do not flush or close the streams. Often, doing so + * would require making non-portable assumptions about the streams' origin and further use. This means that both + * streams' close() methods must be called after copying. if one omits this step, then the stream resources + * (sockets, file descriptors) are released when the associated Stream is garbage-collected. It is not a good idea to + * rely on this mechanism. For a good overview of the distinction between "memory management" and "resource management", + * see this UnixReview article + *

+ *

+ * For each copy method, a variant is provided that allows the caller to specify the buffer size (the + * default is 4k). As the buffer size can have a fairly large impact on speed, this may be worth tweaking. Often "large + * buffer -> faster" does not hold, even for large data transfers. + *

+ *

+ * For byte-to-char methods, a copy variant allows the encoding to be selected (otherwise the platform + * default is used). + *

+ *

+ * The copy methods use an internal buffer when copying. It is therefore advisable not to + * deliberately wrap the stream arguments to the copy methods in Buffered* streams. For + * example, don't do the following: + *

+ * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); + *

+ * The rationale is as follows: + *

+ *

+ * Imagine that an InputStream's read() is a very expensive operation, which would usually suggest wrapping in a + * BufferedInputStream. The BufferedInputStream works by issuing infrequent + * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to fill an + * internal buffer, from which further read requests can inexpensively get their data (until the buffer + * runs out). + *

+ *

+ * However, the copy methods do the same thing, keeping an internal buffer, populated by + * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers (or three if the destination stream + * is also buffered) is pointless, and the unnecessary buffer management hurts performance slightly (about 3%, according + * to some simple experiments). + *

+ * + * @author Peter Donald + * @author Jeff Turner + * + * @since 4.0 + */ + +/* + * Behold, intrepid explorers; a map of this class: Method Input Output Dependency ------ ----- ------ ------- 1 copy + * InputStream OutputStream (primitive) 2 copy Reader Writer (primitive) 3 copy InputStream Writer 2 4 toString + * InputStream String 3 5 toByteArray InputStream byte[] 1 6 copy Reader OutputStream 2 7 toString Reader String 2 8 + * toByteArray Reader byte[] 6 9 copy String OutputStream 2 10 copy String Writer (trivial) 11 toByteArray String byte[] + * 9 12 copy byte[] Writer 3 13 toString byte[] String 12 14 copy byte[] OutputStream (trivial) Note that only the first + * two methods shuffle bytes; the rest use these two, or (if possible) copy using native Java copy methods. As there are + * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods. + */ + +public final class IOUtil +{ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; + + /** + * Private constructor to prevent instantiation. + */ + private IOUtil() + { + } + + /////////////////////////////////////////////////////////////// + // Core copy methods + /////////////////////////////////////////////////////////////// + + /** + * Copy bytes from an InputStream to an OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final InputStream input, final OutputStream output ) + throws IOException + { + input.transferTo( output ); + } + + /** + * Copy bytes from an InputStream to an OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final OutputStream output, final int bufferSize ) + throws IOException + { + final byte[] buffer = new byte[bufferSize]; + int n = 0; + while ( 0 <= ( n = input.read( buffer ) ) ) + { + output.write( buffer, 0, n ); + } + } + + /** + * Copy chars from a Reader to a Writer. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final Reader input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy chars from a Reader to a Writer. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final Reader input, final Writer output, final int bufferSize ) + throws IOException + { + final char[] buffer = new char[bufferSize]; + int n = 0; + while ( 0 <= ( n = input.read( buffer ) ) ) + { + output.write( buffer, 0, n ); + } + output.flush(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // InputStream -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // InputStream -> Writer + + /** + * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final int bufferSize ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input ); + copy( in, output, bufferSize ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final String encoding ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input, encoding ); + copy( in, output ); + } + + /** + * Copy and convert bytes from an InputStream to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final InputStream input, final Writer output, final String encoding, final int bufferSize ) + throws IOException + { + final InputStreamReader in = new InputStreamReader( input, encoding ); + copy( in, output, bufferSize ); + } + + /////////////////////////////////////////////////////////////// + // InputStream -> String + + /** + * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final InputStream input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /** + * @return Get the contents of an InputStream as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final String encoding ) + throws IOException + { + return toString( input, encoding, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final InputStream input, final String encoding, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, encoding, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // InputStream -> byte[] + + /** + * @return Get the contents of an InputStream as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final InputStream input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of an InputStream as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final InputStream input, final int bufferSize ) + throws IOException + { + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // Reader -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // Reader -> OutputStream + /** + * Serialize chars from a Reader to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final Reader input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a Reader to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final Reader input, final OutputStream output, final int bufferSize ) + throws IOException + { + final OutputStreamWriter out = new OutputStreamWriter( output ); + copy( input, out, bufferSize ); + // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush + // here. + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // Reader -> String + /** + * @return Get the contents of a Reader as a String. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final Reader input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a Reader as a String. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final Reader input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // Reader -> byte[] + /** + * @return Get the contents of a Reader as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final Reader input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a Reader as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final Reader input, final int bufferSize ) + throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // String -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // String -> OutputStream + + /** + * Serialize chars from a String to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final String input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Serialize chars from a String to bytes on an OutputStream, and flush the + * OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final String input, final OutputStream output, final int bufferSize ) + throws IOException + { + final StringReader in = new StringReader( input ); + final OutputStreamWriter out = new OutputStreamWriter( output ); + copy( in, out, bufferSize ); + // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush + // here. + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // String -> Writer + + /** + * Copy chars from a String to a Writer. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final String input, final Writer output ) + throws IOException + { + output.write( input ); + } + + /** + * Copy bytes from an InputStream to an OutputStream, with buffering. This is equivalent + * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to + * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed + * after the copy. + * @param input to convert + * @param output the result + * @deprecated Buffering streams is actively harmful! See the class description as to why. Use + * {@link #copy(InputStream, OutputStream)} instead. + * @throws IOException io issue + */ + @Deprecated + public static void bufferedCopy( final InputStream input, final OutputStream output ) + throws IOException + { + final BufferedInputStream in = new BufferedInputStream( input ); + final BufferedOutputStream out = new BufferedOutputStream( output ); + copy( in, out ); + out.flush(); + } + + /////////////////////////////////////////////////////////////// + // String -> byte[] + /** + * @return Get the contents of a String as a byte[]. + * @param input to convert + * @throws IOException io issue + */ + public static byte[] toByteArray( final String input ) + throws IOException + { + return toByteArray( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a String as a byte[]. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static byte[] toByteArray( final String input, final int bufferSize ) + throws IOException + { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy( input, output, bufferSize ); + return output.toByteArray(); + } + + /////////////////////////////////////////////////////////////// + // Derived copy methods + // byte[] -> * + /////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////// + // byte[] -> Writer + + /** + * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default + * encoding is used for the byte-to-char conversion. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final int bufferSize ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, bufferSize ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final String encoding ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, encoding ); + } + + /** + * Copy and convert bytes from a byte[] to chars on a Writer, using the specified + * encoding. + * @param input to convert + * @param output the result + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final Writer output, final String encoding, final int bufferSize ) + throws IOException + { + final ByteArrayInputStream in = new ByteArrayInputStream( input ); + copy( in, output, encoding, bufferSize ); + } + + /////////////////////////////////////////////////////////////// + // byte[] -> String + + /** + * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @throws IOException io issue + */ + public static String toString( final byte[] input ) + throws IOException + { + return toString( input, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the + * byte-to-char conversion. + * @param input to convert + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static String toString( final byte[] input, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, bufferSize ); + return sw.toString(); + } + + /** + * @return Get the contents of a byte[] as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @throws IOException io issue + */ + public static String toString( final byte[] input, final String encoding ) + throws IOException + { + return toString( input, encoding, DEFAULT_BUFFER_SIZE ); + } + + /** + * @return the contents of a byte[] as a String. + * @param input to convert + * @param encoding The name of a supported character encoding. See the + * IANA Charset Registry for a list of valid + * encoding types. + * @param bufferSize Size of internal buffer to use. + * + * @throws IOException io issue + */ + public static String toString( final byte[] input, final String encoding, final int bufferSize ) + throws IOException + { + final StringWriter sw = new StringWriter(); + copy( input, sw, encoding, bufferSize ); + return sw.toString(); + } + + /////////////////////////////////////////////////////////////// + // byte[] -> OutputStream + + /** + * Copy bytes from a byte[] to an OutputStream. + * @param input to convert + * @param output the result + * @throws IOException io issue + */ + public static void copy( final byte[] input, final OutputStream output ) + throws IOException + { + copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + /** + * Copy bytes from a byte[] to an OutputStream. + * @param input to convert + * @param output the result + * @param bufferSize Size of internal buffer to use. + * @throws IOException io issue + */ + public static void copy( final byte[] input, final OutputStream output, final int bufferSize ) + throws IOException + { + output.write( input ); + } + + /** + * Compare the contents of two Streams to determine if they are equal or not. + * + * @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 IOException io issue + */ + public static boolean contentEquals( final InputStream input1, final InputStream input2 ) + throws IOException + { + final InputStream bufferedInput1 = new BufferedInputStream( input1 ); + final InputStream bufferedInput2 = new BufferedInputStream( input2 ); + + int ch = bufferedInput1.read(); + while ( 0 <= ch ) + { + final int ch2 = bufferedInput2.read(); + if ( ch != ch2 ) + { + return false; + } + ch = bufferedInput1.read(); + } + + final int ch2 = bufferedInput2.read(); + if ( 0 <= ch2 ) + { + return false; + } + else + { + return true; + } + } + + // ---------------------------------------------------------------------- + // closeXXX() + // ---------------------------------------------------------------------- + + /** + * Closes the input stream. The input stream can be null and any IOException's will be swallowed. + * + * @param inputStream The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( InputStream inputStream ) + { + if ( inputStream == null ) + { + return; + } + + try + { + inputStream.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes a channel. Channel can be null and any IOException's will be swallowed. + * + * @param channel The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Channel channel ) + { + if ( channel == null ) + { + return; + } + + try + { + channel.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the output stream. The output stream can be null and any IOException's will be swallowed. + * + * @param outputStream The stream to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( OutputStream outputStream ) + { + if ( outputStream == null ) + { + return; + } + + try + { + outputStream.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the reader. The reader can be null and any IOException's will be swallowed. + * + * @param reader The reader to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Reader reader ) + { + if ( reader == null ) + { + return; + } + + try + { + reader.close(); + } + catch ( IOException ex ) + { + // ignore + } + } + + /** + * Closes the writer. The writer can be null and any IOException's will be swallowed. + * + * @param writer The writer to close. + * @deprecated use try-with-resources instead + */ + @Deprecated + public static void close( Writer writer ) + { + if ( writer == null ) + { + return; + } + + try + { + writer.close(); + } + catch ( IOException ex ) + { + // ignore + } + } +} From bc5b0ab5419e8d1a4acd2ed8a4ff158cb325257f Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sat, 2 Jan 2021 23:14:56 +0000 Subject: [PATCH 4/9] Reducing duplicate code in MRJAR using VersionSpecifics class Signed-off-by: Markus KARG --- .../plexus/util/CommonImplementation.java | 29 + .../java/org/codehaus/plexus/util/IOUtil.java | 4 +- .../plexus/util/VersionSpecifics.java | 13 + .../org/codehaus/plexus/util/IOUtil.java | 886 ------------------ .../plexus/util/VersionSpecifics.java | 31 + .../org/codehaus/plexus/util/IOUtil.java | 886 ------------------ .../plexus/util/VersionSpecifics.java | 25 + 7 files changed, 100 insertions(+), 1774 deletions(-) create mode 100644 src/main/java/org/codehaus/plexus/util/CommonImplementation.java create mode 100644 src/main/java/org/codehaus/plexus/util/VersionSpecifics.java delete mode 100644 src/main/java10/org/codehaus/plexus/util/IOUtil.java create mode 100644 src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java delete mode 100644 src/main/java9/org/codehaus/plexus/util/IOUtil.java create mode 100644 src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java diff --git a/src/main/java/org/codehaus/plexus/util/CommonImplementation.java b/src/main/java/org/codehaus/plexus/util/CommonImplementation.java new file mode 100644 index 00000000..16923d9c --- /dev/null +++ b/src/main/java/org/codehaus/plexus/util/CommonImplementation.java @@ -0,0 +1,29 @@ +package org.codehaus.plexus.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +/** + * Fallback implementation for all Java SE versions not + * overwriting a method version-specifically. + */ +abstract class CommonImplementation +{ + private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; + + void copy( final InputStream input, final OutputStream output ) + throws IOException + { + IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + void copy( final Reader input, final Writer output ) + throws IOException + { + IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); + } + +} diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index 3fab8411..5ba3fb73 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -156,7 +156,7 @@ private IOUtil() public static void copy( final InputStream input, final OutputStream output ) throws IOException { - copy( input, output, DEFAULT_BUFFER_SIZE ); + VersionSpecifics.INSTANCE.copy( input, output ); } /** @@ -186,7 +186,7 @@ public static void copy( final InputStream input, final OutputStream output, fin public static void copy( final Reader input, final Writer output ) throws IOException { - copy( input, output, DEFAULT_BUFFER_SIZE ); + VersionSpecifics.INSTANCE.copy( input, output ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java new file mode 100644 index 00000000..de3e7d8a --- /dev/null +++ b/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java @@ -0,0 +1,13 @@ +package org.codehaus.plexus.util; + +/** + * Implementation specific to Java SE 8 version. + */ +final class VersionSpecifics extends CommonImplementation +{ + static final VersionSpecifics INSTANCE = new VersionSpecifics(); + + private VersionSpecifics() { + // singleton + } +} diff --git a/src/main/java10/org/codehaus/plexus/util/IOUtil.java b/src/main/java10/org/codehaus/plexus/util/IOUtil.java deleted file mode 100644 index fdb64163..00000000 --- a/src/main/java10/org/codehaus/plexus/util/IOUtil.java +++ /dev/null @@ -1,886 +0,0 @@ -package org.codehaus.plexus.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.codehaus.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Turbine" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact codehaus@codehaus.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Turbine", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.channels.Channel; - -/** - * General IO Stream manipulation. - *

- * This class provides static utility methods for input/output operations, particularly buffered copying between sources - * (InputStream, Reader, String and byte[]) and destinations - * (OutputStream, Writer, String and byte[]). - *

- *

- * Unless otherwise noted, these copy methods do not flush or close the streams. Often, doing so - * would require making non-portable assumptions about the streams' origin and further use. This means that both - * streams' close() methods must be called after copying. if one omits this step, then the stream resources - * (sockets, file descriptors) are released when the associated Stream is garbage-collected. It is not a good idea to - * rely on this mechanism. For a good overview of the distinction between "memory management" and "resource management", - * see this UnixReview article - *

- *

- * For each copy method, a variant is provided that allows the caller to specify the buffer size (the - * default is 4k). As the buffer size can have a fairly large impact on speed, this may be worth tweaking. Often "large - * buffer -> faster" does not hold, even for large data transfers. - *

- *

- * For byte-to-char methods, a copy variant allows the encoding to be selected (otherwise the platform - * default is used). - *

- *

- * The copy methods use an internal buffer when copying. It is therefore advisable not to - * deliberately wrap the stream arguments to the copy methods in Buffered* streams. For - * example, don't do the following: - *

- * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); - *

- * The rationale is as follows: - *

- *

- * Imagine that an InputStream's read() is a very expensive operation, which would usually suggest wrapping in a - * BufferedInputStream. The BufferedInputStream works by issuing infrequent - * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to fill an - * internal buffer, from which further read requests can inexpensively get their data (until the buffer - * runs out). - *

- *

- * However, the copy methods do the same thing, keeping an internal buffer, populated by - * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers (or three if the destination stream - * is also buffered) is pointless, and the unnecessary buffer management hurts performance slightly (about 3%, according - * to some simple experiments). - *

- * - * @author Peter Donald - * @author Jeff Turner - * - * @since 4.0 - */ - -/* - * Behold, intrepid explorers; a map of this class: Method Input Output Dependency ------ ----- ------ ------- 1 copy - * InputStream OutputStream (primitive) 2 copy Reader Writer (primitive) 3 copy InputStream Writer 2 4 toString - * InputStream String 3 5 toByteArray InputStream byte[] 1 6 copy Reader OutputStream 2 7 toString Reader String 2 8 - * toByteArray Reader byte[] 6 9 copy String OutputStream 2 10 copy String Writer (trivial) 11 toByteArray String byte[] - * 9 12 copy byte[] Writer 3 13 toString byte[] String 12 14 copy byte[] OutputStream (trivial) Note that only the first - * two methods shuffle bytes; the rest use these two, or (if possible) copy using native Java copy methods. As there are - * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods. - */ - -public final class IOUtil -{ - private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; - - /** - * Private constructor to prevent instantiation. - */ - private IOUtil() - { - } - - /////////////////////////////////////////////////////////////// - // Core copy methods - /////////////////////////////////////////////////////////////// - - /** - * Copy bytes from an InputStream to an OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final InputStream input, final OutputStream output ) - throws IOException - { - input.transferTo( output ); - } - - /** - * Copy bytes from an InputStream to an OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final OutputStream output, final int bufferSize ) - throws IOException - { - final byte[] buffer = new byte[bufferSize]; - int n = 0; - while ( 0 <= ( n = input.read( buffer ) ) ) - { - output.write( buffer, 0, n ); - } - } - - /** - * Copy chars from a Reader to a Writer. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final Reader input, final Writer output ) - throws IOException - { - input.transferTo( output ); - } - - /** - * Copy chars from a Reader to a Writer. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final Reader input, final Writer output, final int bufferSize ) - throws IOException - { - final char[] buffer = new char[bufferSize]; - int n = 0; - while ( 0 <= ( n = input.read( buffer ) ) ) - { - output.write( buffer, 0, n ); - } - output.flush(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // InputStream -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // InputStream -> Writer - - /** - * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final int bufferSize ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input ); - copy( in, output, bufferSize ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final String encoding ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input, encoding ); - copy( in, output ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final String encoding, final int bufferSize ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input, encoding ); - copy( in, output, bufferSize ); - } - - /////////////////////////////////////////////////////////////// - // InputStream -> String - - /** - * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final InputStream input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /** - * @return Get the contents of an InputStream as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final String encoding ) - throws IOException - { - return toString( input, encoding, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final String encoding, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, encoding, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // InputStream -> byte[] - - /** - * @return Get the contents of an InputStream as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final InputStream input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final InputStream input, final int bufferSize ) - throws IOException - { - final ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // Reader -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // Reader -> OutputStream - /** - * Serialize chars from a Reader to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final Reader input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Serialize chars from a Reader to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final Reader input, final OutputStream output, final int bufferSize ) - throws IOException - { - final OutputStreamWriter out = new OutputStreamWriter( output ); - copy( input, out, bufferSize ); - // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush - // here. - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // Reader -> String - /** - * @return Get the contents of a Reader as a String. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final Reader input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a Reader as a String. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final Reader input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // Reader -> byte[] - /** - * @return Get the contents of a Reader as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final Reader input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a Reader as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final Reader input, final int bufferSize ) - throws IOException - { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // String -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // String -> OutputStream - - /** - * Serialize chars from a String to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final String input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Serialize chars from a String to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final String input, final OutputStream output, final int bufferSize ) - throws IOException - { - final StringReader in = new StringReader( input ); - final OutputStreamWriter out = new OutputStreamWriter( output ); - copy( in, out, bufferSize ); - // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush - // here. - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // String -> Writer - - /** - * Copy chars from a String to a Writer. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final String input, final Writer output ) - throws IOException - { - output.write( input ); - } - - /** - * Copy bytes from an InputStream to an OutputStream, with buffering. This is equivalent - * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to - * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed - * after the copy. - * @param input to convert - * @param output the result - * @deprecated Buffering streams is actively harmful! See the class description as to why. Use - * {@link #copy(InputStream, OutputStream)} instead. - * @throws IOException io issue - */ - @Deprecated - public static void bufferedCopy( final InputStream input, final OutputStream output ) - throws IOException - { - final BufferedInputStream in = new BufferedInputStream( input ); - final BufferedOutputStream out = new BufferedOutputStream( output ); - copy( in, out ); - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // String -> byte[] - /** - * @return Get the contents of a String as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final String input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a String as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final String input, final int bufferSize ) - throws IOException - { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // byte[] -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // byte[] -> Writer - - /** - * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final int bufferSize ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, bufferSize ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final String encoding ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, encoding ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final String encoding, final int bufferSize ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, encoding, bufferSize ); - } - - /////////////////////////////////////////////////////////////// - // byte[] -> String - - /** - * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final byte[] input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final byte[] input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /** - * @return Get the contents of a byte[] as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static String toString( final byte[] input, final String encoding ) - throws IOException - { - return toString( input, encoding, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return the contents of a byte[] as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * - * @throws IOException io issue - */ - public static String toString( final byte[] input, final String encoding, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, encoding, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // byte[] -> OutputStream - - /** - * Copy bytes from a byte[] to an OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final byte[] input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy bytes from a byte[] to an OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final OutputStream output, final int bufferSize ) - throws IOException - { - output.write( input ); - } - - /** - * Compare the contents of two Streams to determine if they are equal or not. - * - * @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 IOException io issue - */ - public static boolean contentEquals( final InputStream input1, final InputStream input2 ) - throws IOException - { - final InputStream bufferedInput1 = new BufferedInputStream( input1 ); - final InputStream bufferedInput2 = new BufferedInputStream( input2 ); - - int ch = bufferedInput1.read(); - while ( 0 <= ch ) - { - final int ch2 = bufferedInput2.read(); - if ( ch != ch2 ) - { - return false; - } - ch = bufferedInput1.read(); - } - - final int ch2 = bufferedInput2.read(); - if ( 0 <= ch2 ) - { - return false; - } - else - { - return true; - } - } - - // ---------------------------------------------------------------------- - // closeXXX() - // ---------------------------------------------------------------------- - - /** - * Closes the input stream. The input stream can be null and any IOException's will be swallowed. - * - * @param inputStream The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( InputStream inputStream ) - { - if ( inputStream == null ) - { - return; - } - - try - { - inputStream.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes a channel. Channel can be null and any IOException's will be swallowed. - * - * @param channel The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Channel channel ) - { - if ( channel == null ) - { - return; - } - - try - { - channel.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the output stream. The output stream can be null and any IOException's will be swallowed. - * - * @param outputStream The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( OutputStream outputStream ) - { - if ( outputStream == null ) - { - return; - } - - try - { - outputStream.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the reader. The reader can be null and any IOException's will be swallowed. - * - * @param reader The reader to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Reader reader ) - { - if ( reader == null ) - { - return; - } - - try - { - reader.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the writer. The writer can be null and any IOException's will be swallowed. - * - * @param writer The writer to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Writer writer ) - { - if ( writer == null ) - { - return; - } - - try - { - writer.close(); - } - catch ( IOException ex ) - { - // ignore - } - } -} diff --git a/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java new file mode 100644 index 00000000..ae1d050a --- /dev/null +++ b/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java @@ -0,0 +1,31 @@ +package org.codehaus.plexus.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +/** + * Implementation specific to Java SE 10 version. + */ +final class VersionSpecifics extends CommonImplementation +{ + static final VersionSpecifics INSTANCE = new VersionSpecifics(); + + private VersionSpecifics() { + // singleton + } + + void copy( final InputStream input, final OutputStream output ) + throws IOException + { + input.transferTo( output ); + } + + void copy( final Reader input, final Writer output ) + throws IOException + { + input.transferTo( output ); + } +} diff --git a/src/main/java9/org/codehaus/plexus/util/IOUtil.java b/src/main/java9/org/codehaus/plexus/util/IOUtil.java deleted file mode 100644 index 0b2ae40b..00000000 --- a/src/main/java9/org/codehaus/plexus/util/IOUtil.java +++ /dev/null @@ -1,886 +0,0 @@ -package org.codehaus.plexus.util; - -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.codehaus.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Turbine" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact codehaus@codehaus.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache Turbine", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.channels.Channel; - -/** - * General IO Stream manipulation. - *

- * This class provides static utility methods for input/output operations, particularly buffered copying between sources - * (InputStream, Reader, String and byte[]) and destinations - * (OutputStream, Writer, String and byte[]). - *

- *

- * Unless otherwise noted, these copy methods do not flush or close the streams. Often, doing so - * would require making non-portable assumptions about the streams' origin and further use. This means that both - * streams' close() methods must be called after copying. if one omits this step, then the stream resources - * (sockets, file descriptors) are released when the associated Stream is garbage-collected. It is not a good idea to - * rely on this mechanism. For a good overview of the distinction between "memory management" and "resource management", - * see this UnixReview article - *

- *

- * For each copy method, a variant is provided that allows the caller to specify the buffer size (the - * default is 4k). As the buffer size can have a fairly large impact on speed, this may be worth tweaking. Often "large - * buffer -> faster" does not hold, even for large data transfers. - *

- *

- * For byte-to-char methods, a copy variant allows the encoding to be selected (otherwise the platform - * default is used). - *

- *

- * The copy methods use an internal buffer when copying. It is therefore advisable not to - * deliberately wrap the stream arguments to the copy methods in Buffered* streams. For - * example, don't do the following: - *

- * copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) ); - *

- * The rationale is as follows: - *

- *

- * Imagine that an InputStream's read() is a very expensive operation, which would usually suggest wrapping in a - * BufferedInputStream. The BufferedInputStream works by issuing infrequent - * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to fill an - * internal buffer, from which further read requests can inexpensively get their data (until the buffer - * runs out). - *

- *

- * However, the copy methods do the same thing, keeping an internal buffer, populated by - * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers (or three if the destination stream - * is also buffered) is pointless, and the unnecessary buffer management hurts performance slightly (about 3%, according - * to some simple experiments). - *

- * - * @author Peter Donald - * @author Jeff Turner - * - * @since 4.0 - */ - -/* - * Behold, intrepid explorers; a map of this class: Method Input Output Dependency ------ ----- ------ ------- 1 copy - * InputStream OutputStream (primitive) 2 copy Reader Writer (primitive) 3 copy InputStream Writer 2 4 toString - * InputStream String 3 5 toByteArray InputStream byte[] 1 6 copy Reader OutputStream 2 7 toString Reader String 2 8 - * toByteArray Reader byte[] 6 9 copy String OutputStream 2 10 copy String Writer (trivial) 11 toByteArray String byte[] - * 9 12 copy byte[] Writer 3 13 toString byte[] String 12 14 copy byte[] OutputStream (trivial) Note that only the first - * two methods shuffle bytes; the rest use these two, or (if possible) copy using native Java copy methods. As there are - * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods. - */ - -public final class IOUtil -{ - private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; - - /** - * Private constructor to prevent instantiation. - */ - private IOUtil() - { - } - - /////////////////////////////////////////////////////////////// - // Core copy methods - /////////////////////////////////////////////////////////////// - - /** - * Copy bytes from an InputStream to an OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final InputStream input, final OutputStream output ) - throws IOException - { - input.transferTo( output ); - } - - /** - * Copy bytes from an InputStream to an OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final OutputStream output, final int bufferSize ) - throws IOException - { - final byte[] buffer = new byte[bufferSize]; - int n = 0; - while ( 0 <= ( n = input.read( buffer ) ) ) - { - output.write( buffer, 0, n ); - } - } - - /** - * Copy chars from a Reader to a Writer. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final Reader input, final Writer output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy chars from a Reader to a Writer. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final Reader input, final Writer output, final int bufferSize ) - throws IOException - { - final char[] buffer = new char[bufferSize]; - int n = 0; - while ( 0 <= ( n = input.read( buffer ) ) ) - { - output.write( buffer, 0, n ); - } - output.flush(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // InputStream -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // InputStream -> Writer - - /** - * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final int bufferSize ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input ); - copy( in, output, bufferSize ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final String encoding ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input, encoding ); - copy( in, output ); - } - - /** - * Copy and convert bytes from an InputStream to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final InputStream input, final Writer output, final String encoding, final int bufferSize ) - throws IOException - { - final InputStreamReader in = new InputStreamReader( input, encoding ); - copy( in, output, bufferSize ); - } - - /////////////////////////////////////////////////////////////// - // InputStream -> String - - /** - * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final InputStream input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /** - * @return Get the contents of an InputStream as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final String encoding ) - throws IOException - { - return toString( input, encoding, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final InputStream input, final String encoding, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, encoding, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // InputStream -> byte[] - - /** - * @return Get the contents of an InputStream as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final InputStream input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of an InputStream as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final InputStream input, final int bufferSize ) - throws IOException - { - final ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // Reader -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // Reader -> OutputStream - /** - * Serialize chars from a Reader to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final Reader input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Serialize chars from a Reader to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final Reader input, final OutputStream output, final int bufferSize ) - throws IOException - { - final OutputStreamWriter out = new OutputStreamWriter( output ); - copy( input, out, bufferSize ); - // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush - // here. - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // Reader -> String - /** - * @return Get the contents of a Reader as a String. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final Reader input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a Reader as a String. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final Reader input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // Reader -> byte[] - /** - * @return Get the contents of a Reader as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final Reader input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a Reader as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final Reader input, final int bufferSize ) - throws IOException - { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // String -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // String -> OutputStream - - /** - * Serialize chars from a String to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final String input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Serialize chars from a String to bytes on an OutputStream, and flush the - * OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final String input, final OutputStream output, final int bufferSize ) - throws IOException - { - final StringReader in = new StringReader( input ); - final OutputStreamWriter out = new OutputStreamWriter( output ); - copy( in, out, bufferSize ); - // NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush - // here. - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // String -> Writer - - /** - * Copy chars from a String to a Writer. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final String input, final Writer output ) - throws IOException - { - output.write( input ); - } - - /** - * Copy bytes from an InputStream to an OutputStream, with buffering. This is equivalent - * to passing a {@link java.io.BufferedInputStream} and {@link java.io.BufferedOutputStream} to - * {@link #copy(InputStream, OutputStream)}, and flushing the output stream afterwards. The streams are not closed - * after the copy. - * @param input to convert - * @param output the result - * @deprecated Buffering streams is actively harmful! See the class description as to why. Use - * {@link #copy(InputStream, OutputStream)} instead. - * @throws IOException io issue - */ - @Deprecated - public static void bufferedCopy( final InputStream input, final OutputStream output ) - throws IOException - { - final BufferedInputStream in = new BufferedInputStream( input ); - final BufferedOutputStream out = new BufferedOutputStream( output ); - copy( in, out ); - out.flush(); - } - - /////////////////////////////////////////////////////////////// - // String -> byte[] - /** - * @return Get the contents of a String as a byte[]. - * @param input to convert - * @throws IOException io issue - */ - public static byte[] toByteArray( final String input ) - throws IOException - { - return toByteArray( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a String as a byte[]. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static byte[] toByteArray( final String input, final int bufferSize ) - throws IOException - { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - copy( input, output, bufferSize ); - return output.toByteArray(); - } - - /////////////////////////////////////////////////////////////// - // Derived copy methods - // byte[] -> * - /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// - // byte[] -> Writer - - /** - * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer. The platform's default - * encoding is used for the byte-to-char conversion. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final int bufferSize ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, bufferSize ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final String encoding ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, encoding ); - } - - /** - * Copy and convert bytes from a byte[] to chars on a Writer, using the specified - * encoding. - * @param input to convert - * @param output the result - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final Writer output, final String encoding, final int bufferSize ) - throws IOException - { - final ByteArrayInputStream in = new ByteArrayInputStream( input ); - copy( in, output, encoding, bufferSize ); - } - - /////////////////////////////////////////////////////////////// - // byte[] -> String - - /** - * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @throws IOException io issue - */ - public static String toString( final byte[] input ) - throws IOException - { - return toString( input, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return Get the contents of a byte[] as a String. The platform's default encoding is used for the - * byte-to-char conversion. - * @param input to convert - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static String toString( final byte[] input, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, bufferSize ); - return sw.toString(); - } - - /** - * @return Get the contents of a byte[] as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @throws IOException io issue - */ - public static String toString( final byte[] input, final String encoding ) - throws IOException - { - return toString( input, encoding, DEFAULT_BUFFER_SIZE ); - } - - /** - * @return the contents of a byte[] as a String. - * @param input to convert - * @param encoding The name of a supported character encoding. See the - * IANA Charset Registry for a list of valid - * encoding types. - * @param bufferSize Size of internal buffer to use. - * - * @throws IOException io issue - */ - public static String toString( final byte[] input, final String encoding, final int bufferSize ) - throws IOException - { - final StringWriter sw = new StringWriter(); - copy( input, sw, encoding, bufferSize ); - return sw.toString(); - } - - /////////////////////////////////////////////////////////////// - // byte[] -> OutputStream - - /** - * Copy bytes from a byte[] to an OutputStream. - * @param input to convert - * @param output the result - * @throws IOException io issue - */ - public static void copy( final byte[] input, final OutputStream output ) - throws IOException - { - copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - /** - * Copy bytes from a byte[] to an OutputStream. - * @param input to convert - * @param output the result - * @param bufferSize Size of internal buffer to use. - * @throws IOException io issue - */ - public static void copy( final byte[] input, final OutputStream output, final int bufferSize ) - throws IOException - { - output.write( input ); - } - - /** - * Compare the contents of two Streams to determine if they are equal or not. - * - * @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 IOException io issue - */ - public static boolean contentEquals( final InputStream input1, final InputStream input2 ) - throws IOException - { - final InputStream bufferedInput1 = new BufferedInputStream( input1 ); - final InputStream bufferedInput2 = new BufferedInputStream( input2 ); - - int ch = bufferedInput1.read(); - while ( 0 <= ch ) - { - final int ch2 = bufferedInput2.read(); - if ( ch != ch2 ) - { - return false; - } - ch = bufferedInput1.read(); - } - - final int ch2 = bufferedInput2.read(); - if ( 0 <= ch2 ) - { - return false; - } - else - { - return true; - } - } - - // ---------------------------------------------------------------------- - // closeXXX() - // ---------------------------------------------------------------------- - - /** - * Closes the input stream. The input stream can be null and any IOException's will be swallowed. - * - * @param inputStream The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( InputStream inputStream ) - { - if ( inputStream == null ) - { - return; - } - - try - { - inputStream.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes a channel. Channel can be null and any IOException's will be swallowed. - * - * @param channel The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Channel channel ) - { - if ( channel == null ) - { - return; - } - - try - { - channel.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the output stream. The output stream can be null and any IOException's will be swallowed. - * - * @param outputStream The stream to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( OutputStream outputStream ) - { - if ( outputStream == null ) - { - return; - } - - try - { - outputStream.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the reader. The reader can be null and any IOException's will be swallowed. - * - * @param reader The reader to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Reader reader ) - { - if ( reader == null ) - { - return; - } - - try - { - reader.close(); - } - catch ( IOException ex ) - { - // ignore - } - } - - /** - * Closes the writer. The writer can be null and any IOException's will be swallowed. - * - * @param writer The writer to close. - * @deprecated use try-with-resources instead - */ - @Deprecated - public static void close( Writer writer ) - { - if ( writer == null ) - { - return; - } - - try - { - writer.close(); - } - catch ( IOException ex ) - { - // ignore - } - } -} diff --git a/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java new file mode 100644 index 00000000..c72cc7a3 --- /dev/null +++ b/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java @@ -0,0 +1,25 @@ +package org.codehaus.plexus.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +/** + * Implementation specific to Java SE 9 version. + */ +final class VersionSpecifics extends CommonImplementation +{ + static final VersionSpecifics INSTANCE = new VersionSpecifics(); + + private VersionSpecifics() { + // singleton + } + + void copy( final InputStream input, final OutputStream output ) + throws IOException + { + input.transferTo( output ); + } +} From e16dc59a77ef28063084413136407a3f020e5688 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 3 Jan 2021 13:02:23 +0000 Subject: [PATCH 5/9] Reducing number of classes; No singleton but static. Signed-off-by: Markus KARG --- .../plexus/util/CommonImplementation.java | 29 ------------------- .../java/org/codehaus/plexus/util/IOUtil.java | 4 +-- .../plexus/util/VersionSpecifics.java | 22 ++++++++++++-- .../plexus/util/VersionSpecifics.java | 8 ++--- .../plexus/util/VersionSpecifics.java | 12 ++++++-- 5 files changed, 34 insertions(+), 41 deletions(-) delete mode 100644 src/main/java/org/codehaus/plexus/util/CommonImplementation.java diff --git a/src/main/java/org/codehaus/plexus/util/CommonImplementation.java b/src/main/java/org/codehaus/plexus/util/CommonImplementation.java deleted file mode 100644 index 16923d9c..00000000 --- a/src/main/java/org/codehaus/plexus/util/CommonImplementation.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.codehaus.plexus.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; - -/** - * Fallback implementation for all Java SE versions not - * overwriting a method version-specifically. - */ -abstract class CommonImplementation -{ - private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; - - void copy( final InputStream input, final OutputStream output ) - throws IOException - { - IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); - } - - void copy( final Reader input, final Writer output ) - throws IOException - { - IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); - } - -} diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index 5ba3fb73..ff5002d2 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -156,7 +156,7 @@ private IOUtil() public static void copy( final InputStream input, final OutputStream output ) throws IOException { - VersionSpecifics.INSTANCE.copy( input, output ); + VersionSpecifics.copy( input, output ); } /** @@ -186,7 +186,7 @@ public static void copy( final InputStream input, final OutputStream output, fin public static void copy( final Reader input, final Writer output ) throws IOException { - VersionSpecifics.INSTANCE.copy( input, output ); + VersionSpecifics.copy( input, output ); } /** diff --git a/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java index de3e7d8a..e6be5b08 100644 --- a/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java @@ -1,13 +1,31 @@ package org.codehaus.plexus.util; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + /** * Implementation specific to Java SE 8 version. */ -final class VersionSpecifics extends CommonImplementation +final class VersionSpecifics { - static final VersionSpecifics INSTANCE = new VersionSpecifics(); + private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; private VersionSpecifics() { // singleton } + + static void copy( final InputStream input, final OutputStream output ) + throws IOException + { + IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); + } + + static void copy( final Reader input, final Writer output ) + throws IOException + { + IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); + } } diff --git a/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java index ae1d050a..06b385e2 100644 --- a/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java @@ -9,21 +9,19 @@ /** * Implementation specific to Java SE 10 version. */ -final class VersionSpecifics extends CommonImplementation +final class VersionSpecifics { - static final VersionSpecifics INSTANCE = new VersionSpecifics(); - private VersionSpecifics() { // singleton } - void copy( final InputStream input, final OutputStream output ) + static void copy( final InputStream input, final OutputStream output ) throws IOException { input.transferTo( output ); } - void copy( final Reader input, final Writer output ) + static void copy( final Reader input, final Writer output ) throws IOException { input.transferTo( output ); diff --git a/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java index c72cc7a3..b3c08c64 100644 --- a/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java @@ -9,17 +9,23 @@ /** * Implementation specific to Java SE 9 version. */ -final class VersionSpecifics extends CommonImplementation +final class VersionSpecifics { - static final VersionSpecifics INSTANCE = new VersionSpecifics(); + private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; private VersionSpecifics() { // singleton } - void copy( final InputStream input, final OutputStream output ) + static void copy( final InputStream input, final OutputStream output ) throws IOException { input.transferTo( output ); } + + static void copy( final Reader input, final Writer output ) + throws IOException + { + IOUtil.copy( input, output, DEFAULT_BUFFER_SIZE ); + } } From cecd035a846940700fbc62c4eb308e3fb2dba19f Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 3 Jan 2021 17:13:09 +0000 Subject: [PATCH 6/9] Github CI: Build with JDK 15, test with matrix Signed-off-by: Markus KARG --- .github/workflows/maven.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 13b4c47e..a44b5ebf 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -43,10 +43,18 @@ jobs: maven-${{ matrix.os }}-java${{ matrix.java }}- maven-${{ matrix.os }}- - - name: Set up JDK + - name: Set up JDK for building uses: actions/setup-java@v1 with: - java-version: ${{ matrix.java }} + java-version: 15 - name: Build with Maven run: mvn verify javadoc:javadoc -e -B -V + + - name: Set up JDK for testing + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + + - name: Test with Maven + run: mvn verify -e -B -V From 6579a59569428c6a338eb23d94d9a90a508e32a6 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 10 Jan 2021 13:44:14 +0000 Subject: [PATCH 7/9] Revert "Github CI: Build with JDK 15, test with matrix" This reverts commit cecd035a846940700fbc62c4eb308e3fb2dba19f. --- .github/workflows/maven.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index a44b5ebf..13b4c47e 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -43,18 +43,10 @@ jobs: maven-${{ matrix.os }}-java${{ matrix.java }}- maven-${{ matrix.os }}- - - name: Set up JDK for building + - name: Set up JDK uses: actions/setup-java@v1 with: - java-version: 15 + java-version: ${{ matrix.java }} - name: Build with Maven run: mvn verify javadoc:javadoc -e -B -V - - - name: Set up JDK for testing - uses: actions/setup-java@v1 - with: - java-version: ${{ matrix.java }} - - - name: Test with Maven - run: mvn verify -e -B -V From d430deb5191e46000462ce2295aa2fe126267ef6 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 10 Jan 2021 14:10:36 +0000 Subject: [PATCH 8/9] Can build on JDKs before SE 10, too --- pom.xml | 91 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 27 deletions(-) diff --git a/pom.xml b/pom.xml index f34b6334..164776b0 100644 --- a/pom.xml +++ b/pom.xml @@ -105,33 +105,8 @@ limitations under the License. compile - 8 - - - - compile-java-9 - - compile - - - 9 - - ${project.basedir}/src/main/java9 - - true - - - - compile-java-10 - - compile - - - 10 - - ${project.basedir}/src/main/java10 - - true + 1.8 + 1.8 @@ -187,4 +162,66 @@ limitations under the License. + + + jdk9+ + + [9,) + + + + + + maven-compiler-plugin + + + compile-java-9 + + compile + + + 9 + + ${project.basedir}/src/main/java9 + + true + + + + + + + + + + jdk10+ + + [10,) + + + + + + maven-compiler-plugin + + + compile-java-10 + + compile + + + 10 + + ${project.basedir}/src/main/java10 + + true + + + + + + + + + From 3fe65d89181d58a61957c05a5042a8709c2c7554 Mon Sep 17 00:00:00 2001 From: Markus KARG Date: Sun, 24 Jan 2021 17:34:49 +0000 Subject: [PATCH 9/9] Renamed per @rfsholte's request --- .../plexus/util/{VersionSpecifics.java => BaseIOUtil.java} | 6 +----- src/main/java/org/codehaus/plexus/util/IOUtil.java | 6 +++--- .../plexus/util/{VersionSpecifics.java => BaseIOUtil.java} | 6 +----- .../plexus/util/{VersionSpecifics.java => BaseIOUtil.java} | 6 +----- 4 files changed, 6 insertions(+), 18 deletions(-) rename src/main/java/org/codehaus/plexus/util/{VersionSpecifics.java => BaseIOUtil.java} (87%) rename src/main/java10/org/codehaus/plexus/util/{VersionSpecifics.java => BaseIOUtil.java} (85%) rename src/main/java9/org/codehaus/plexus/util/{VersionSpecifics.java => BaseIOUtil.java} (87%) diff --git a/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java/org/codehaus/plexus/util/BaseIOUtil.java similarity index 87% rename from src/main/java/org/codehaus/plexus/util/VersionSpecifics.java rename to src/main/java/org/codehaus/plexus/util/BaseIOUtil.java index e6be5b08..ac2ade02 100644 --- a/src/main/java/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java/org/codehaus/plexus/util/BaseIOUtil.java @@ -9,14 +9,10 @@ /** * Implementation specific to Java SE 8 version. */ -final class VersionSpecifics +abstract class BaseIOUtil { private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; - private VersionSpecifics() { - // singleton - } - static void copy( final InputStream input, final OutputStream output ) throws IOException { diff --git a/src/main/java/org/codehaus/plexus/util/IOUtil.java b/src/main/java/org/codehaus/plexus/util/IOUtil.java index ff5002d2..b431a8d9 100644 --- a/src/main/java/org/codehaus/plexus/util/IOUtil.java +++ b/src/main/java/org/codehaus/plexus/util/IOUtil.java @@ -132,7 +132,7 @@ * method variants to specify buffer size and encoding, each row may correspond to up to 4 methods. */ -public final class IOUtil +public final class IOUtil extends BaseIOUtil { private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; @@ -156,7 +156,7 @@ private IOUtil() public static void copy( final InputStream input, final OutputStream output ) throws IOException { - VersionSpecifics.copy( input, output ); + BaseIOUtil.copy( input, output ); } /** @@ -186,7 +186,7 @@ public static void copy( final InputStream input, final OutputStream output, fin public static void copy( final Reader input, final Writer output ) throws IOException { - VersionSpecifics.copy( input, output ); + BaseIOUtil.copy( input, output ); } /** diff --git a/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java10/org/codehaus/plexus/util/BaseIOUtil.java similarity index 85% rename from src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java rename to src/main/java10/org/codehaus/plexus/util/BaseIOUtil.java index 06b385e2..fc792be3 100644 --- a/src/main/java10/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java10/org/codehaus/plexus/util/BaseIOUtil.java @@ -9,12 +9,8 @@ /** * Implementation specific to Java SE 10 version. */ -final class VersionSpecifics +abstract class BaseIOUtil { - private VersionSpecifics() { - // singleton - } - static void copy( final InputStream input, final OutputStream output ) throws IOException { diff --git a/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java b/src/main/java9/org/codehaus/plexus/util/BaseIOUtil.java similarity index 87% rename from src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java rename to src/main/java9/org/codehaus/plexus/util/BaseIOUtil.java index b3c08c64..7e0826c4 100644 --- a/src/main/java9/org/codehaus/plexus/util/VersionSpecifics.java +++ b/src/main/java9/org/codehaus/plexus/util/BaseIOUtil.java @@ -9,14 +9,10 @@ /** * Implementation specific to Java SE 9 version. */ -final class VersionSpecifics +abstract class BaseIOUtil { private static final int DEFAULT_BUFFER_SIZE = 1024 * 16; - private VersionSpecifics() { - // singleton - } - static void copy( final InputStream input, final OutputStream output ) throws IOException {