You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/10/03 15:56:34 UTC

[commons-io] branch master updated: Reimplement internals to use try-with-resources.

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git


The following commit(s) were added to refs/heads/master by this push:
     new 299be63  Reimplement internals to use try-with-resources.
299be63 is described below

commit 299be6383ddef3472aed05427ad6dfba64abc17e
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Oct 3 11:56:32 2021 -0400

    Reimplement internals to use try-with-resources.
---
 .../apache/commons/io/CloseableURLConnection.java  | 275 +++++++++++++++++++++
 src/main/java/org/apache/commons/io/FileUtils.java |   6 +-
 src/main/java/org/apache/commons/io/IOUtils.java   |  13 +-
 .../apache/commons/io/input/XmlStreamReader.java   |   1 +
 .../java/org/apache/commons/io/IOUtilsTest.java    |   8 +-
 .../io/input/compatibility/XmlStreamReader.java    |   1 +
 6 files changed, 285 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/CloseableURLConnection.java b/src/main/java/org/apache/commons/io/CloseableURLConnection.java
new file mode 100644
index 0000000..6895bfd
--- /dev/null
+++ b/src/main/java/org/apache/commons/io/CloseableURLConnection.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.Permission;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Delegates to a URLConnection while implementing AutoCloseable.
+ */
+class CloseableURLConnection extends URLConnection implements AutoCloseable {
+
+    static CloseableURLConnection open(final URI uri) throws IOException {
+        return open(Objects.requireNonNull(uri, "uri").toURL());
+    }
+
+    static CloseableURLConnection open(final URL url) throws IOException {
+        return new CloseableURLConnection(url.openConnection());
+    }
+
+    private final URLConnection urlConnection;
+
+    CloseableURLConnection(final URLConnection urlConnection) {
+        super(Objects.requireNonNull(urlConnection, "urlConnection").getURL());
+        this.urlConnection = urlConnection;
+    }
+
+    @Override
+    public void addRequestProperty(final String key, final String value) {
+        urlConnection.addRequestProperty(key, value);
+    }
+
+    @Override
+    public void close() {
+        IOUtils.close(urlConnection);
+    }
+
+    @Override
+    public void connect() throws IOException {
+        urlConnection.connect();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        return urlConnection.equals(obj);
+    }
+
+    @Override
+    public boolean getAllowUserInteraction() {
+        return urlConnection.getAllowUserInteraction();
+    }
+
+    @Override
+    public int getConnectTimeout() {
+        return urlConnection.getConnectTimeout();
+    }
+
+    @Override
+    public Object getContent() throws IOException {
+        return urlConnection.getContent();
+    }
+
+    @Override
+    public Object getContent(final Class[] classes) throws IOException {
+        return urlConnection.getContent(classes);
+    }
+
+    @Override
+    public String getContentEncoding() {
+        return urlConnection.getContentEncoding();
+    }
+
+    @Override
+    public int getContentLength() {
+        return urlConnection.getContentLength();
+    }
+
+    @Override
+    public long getContentLengthLong() {
+        return urlConnection.getContentLengthLong();
+    }
+
+    @Override
+    public String getContentType() {
+        return urlConnection.getContentType();
+    }
+
+    @Override
+    public long getDate() {
+        return urlConnection.getDate();
+    }
+
+    @Override
+    public boolean getDefaultUseCaches() {
+        return urlConnection.getDefaultUseCaches();
+    }
+
+    @Override
+    public boolean getDoInput() {
+        return urlConnection.getDoInput();
+    }
+
+    @Override
+    public boolean getDoOutput() {
+        return urlConnection.getDoOutput();
+    }
+
+    @Override
+    public long getExpiration() {
+        return urlConnection.getExpiration();
+    }
+
+    @Override
+    public String getHeaderField(final int n) {
+        return urlConnection.getHeaderField(n);
+    }
+
+    @Override
+    public String getHeaderField(final String name) {
+        return urlConnection.getHeaderField(name);
+    }
+
+    @Override
+    public long getHeaderFieldDate(final String name, final long Default) {
+        return urlConnection.getHeaderFieldDate(name, Default);
+    }
+
+    @Override
+    public int getHeaderFieldInt(final String name, final int Default) {
+        return urlConnection.getHeaderFieldInt(name, Default);
+    }
+
+    @Override
+    public String getHeaderFieldKey(final int n) {
+        return urlConnection.getHeaderFieldKey(n);
+    }
+
+    @Override
+    public long getHeaderFieldLong(final String name, final long Default) {
+        return urlConnection.getHeaderFieldLong(name, Default);
+    }
+
+    @Override
+    public Map<String, List<String>> getHeaderFields() {
+        return urlConnection.getHeaderFields();
+    }
+
+    @Override
+    public long getIfModifiedSince() {
+        return urlConnection.getIfModifiedSince();
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return urlConnection.getInputStream();
+    }
+
+    @Override
+    public long getLastModified() {
+        return urlConnection.getLastModified();
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        return urlConnection.getOutputStream();
+    }
+
+    @Override
+    public Permission getPermission() throws IOException {
+        return urlConnection.getPermission();
+    }
+
+    @Override
+    public int getReadTimeout() {
+        return urlConnection.getReadTimeout();
+    }
+
+    @Override
+    public Map<String, List<String>> getRequestProperties() {
+        return urlConnection.getRequestProperties();
+    }
+
+    @Override
+    public String getRequestProperty(final String key) {
+        return urlConnection.getRequestProperty(key);
+    }
+
+    @Override
+    public URL getURL() {
+        return urlConnection.getURL();
+    }
+
+    @Override
+    public boolean getUseCaches() {
+        return urlConnection.getUseCaches();
+    }
+
+    @Override
+    public int hashCode() {
+        return urlConnection.hashCode();
+    }
+
+    @Override
+    public void setAllowUserInteraction(final boolean allowuserinteraction) {
+        urlConnection.setAllowUserInteraction(allowuserinteraction);
+    }
+
+    @Override
+    public void setConnectTimeout(final int timeout) {
+        urlConnection.setConnectTimeout(timeout);
+    }
+
+    @Override
+    public void setDefaultUseCaches(final boolean defaultusecaches) {
+        urlConnection.setDefaultUseCaches(defaultusecaches);
+    }
+
+    @Override
+    public void setDoInput(final boolean doinput) {
+        urlConnection.setDoInput(doinput);
+    }
+
+    @Override
+    public void setDoOutput(final boolean dooutput) {
+        urlConnection.setDoOutput(dooutput);
+    }
+
+    @Override
+    public void setIfModifiedSince(final long ifmodifiedsince) {
+        urlConnection.setIfModifiedSince(ifmodifiedsince);
+    }
+
+    @Override
+    public void setReadTimeout(final int timeout) {
+        urlConnection.setReadTimeout(timeout);
+    }
+
+    @Override
+    public void setRequestProperty(final String key, final String value) {
+        urlConnection.setRequestProperty(key, value);
+    }
+
+    @Override
+    public void setUseCaches(final boolean usecaches) {
+        urlConnection.setUseCaches(usecaches);
+    }
+
+    @Override
+    public String toString() {
+        return urlConnection.toString();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/io/FileUtils.java b/src/main/java/org/apache/commons/io/FileUtils.java
index 5cc4f05..0a4ba1b 100644
--- a/src/main/java/org/apache/commons/io/FileUtils.java
+++ b/src/main/java/org/apache/commons/io/FileUtils.java
@@ -30,7 +30,6 @@ import java.io.Reader;
 import java.io.UncheckedIOException;
 import java.math.BigInteger;
 import java.net.URL;
-import java.net.URLConnection;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
@@ -1111,15 +1110,12 @@ public class FileUtils {
      */
     public static void copyURLToFile(final URL source, final File destination, final int connectionTimeoutMillis, final int readTimeoutMillis)
         throws IOException {
-        final URLConnection urlConnection = source.openConnection();
-        try {
+        try (final CloseableURLConnection urlConnection = CloseableURLConnection.open(source)) {
             urlConnection.setConnectTimeout(connectionTimeoutMillis);
             urlConnection.setReadTimeout(readTimeoutMillis);
             try (final InputStream stream = urlConnection.getInputStream()) {
                 copyInputStreamToFile(stream, destination);
             }
-        } finally {
-            IOUtils.close(urlConnection);
         }
     }
 
diff --git a/src/main/java/org/apache/commons/io/IOUtils.java b/src/main/java/org/apache/commons/io/IOUtils.java
index ebd5dce..b095623 100644
--- a/src/main/java/org/apache/commons/io/IOUtils.java
+++ b/src/main/java/org/apache/commons/io/IOUtils.java
@@ -2641,25 +2641,22 @@ public class IOUtils {
      * @since 2.4
      */
     public static byte[] toByteArray(final URL url) throws IOException {
-        final URLConnection conn = url.openConnection();
-        try {
-            return IOUtils.toByteArray(conn);
-        } finally {
-            close(conn);
+        try (final CloseableURLConnection urlConnection = CloseableURLConnection.open(url)) {
+            return IOUtils.toByteArray(urlConnection);
         }
     }
 
     /**
      * Gets the contents of a {@code URLConnection} as a {@code byte[]}.
      *
-     * @param urlConn the {@code URLConnection} to read.
+     * @param urlConnection the {@code URLConnection} to read.
      * @return the requested byte array.
      * @throws NullPointerException if the urlConn is null.
      * @throws IOException if an I/O exception occurs.
      * @since 2.4
      */
-    public static byte[] toByteArray(final URLConnection urlConn) throws IOException {
-        try (InputStream inputStream = urlConn.getInputStream()) {
+    public static byte[] toByteArray(final URLConnection urlConnection) throws IOException {
+        try (InputStream inputStream = urlConnection.getInputStream()) {
             return IOUtils.toByteArray(inputStream);
         }
     }
diff --git a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java
index 1d0da4f..5a490bf 100644
--- a/src/main/java/org/apache/commons/io/input/XmlStreamReader.java
+++ b/src/main/java/org/apache/commons/io/input/XmlStreamReader.java
@@ -507,6 +507,7 @@ public class XmlStreamReader extends Reader {
      *         the URL.
      */
     public XmlStreamReader(final URL url) throws IOException {
+        // TODO URLConnection leak.
         this(Objects.requireNonNull(url, "url").openConnection(), null);
     }
 
diff --git a/src/test/java/org/apache/commons/io/IOUtilsTest.java b/src/test/java/org/apache/commons/io/IOUtilsTest.java
index 838d17d..9b72141 100644
--- a/src/test/java/org/apache/commons/io/IOUtilsTest.java
+++ b/src/test/java/org/apache/commons/io/IOUtilsTest.java
@@ -50,7 +50,6 @@ import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URI;
 import java.net.URL;
-import java.net.URLConnection;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.Selector;
@@ -1556,12 +1555,9 @@ public class IOUtilsTest {
 
     @Test
     public void testToByteArray_URLConnection() throws Exception {
-        final URLConnection urlConn = testFile.toURI().toURL().openConnection();
         final byte[] actual;
-        try {
-            actual = IOUtils.toByteArray(urlConn);
-        } finally {
-            IOUtils.close(urlConn);
+        try (final CloseableURLConnection urlConnection = CloseableURLConnection.open(testFile.toURI())) {
+            actual = IOUtils.toByteArray(urlConnection);
         }
         assertEquals(FILE_SIZE, actual.length);
     }
diff --git a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java
index 0b4751f..04a0b4b 100644
--- a/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java
+++ b/src/test/java/org/apache/commons/io/input/compatibility/XmlStreamReader.java
@@ -491,6 +491,7 @@ public class XmlStreamReader extends Reader {
      *         the URL.
      */
     public XmlStreamReader(final URL url) throws IOException {
+        // TODO URLConnection leak.
         this(url.openConnection());
     }