Add CloseShieldChannel to close-shielded NIO Channels
- Only convert set to array if required
- Extract constant
- Use the simple class name for CloseShieldChannel in toString()
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 861107d..c28573c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -66,7 +66,7 @@
<action dev="pkarwasz" type="add" due-to="Piotr P. Karwasz">Add org.apache.commons.io.file.PathUtils.getPath(String, String).</action>
<action dev="ggregory" type="add" due-to="Gary Gregory">Add org.apache.commons.io.channels.ByteArraySeekableByteChannel.</action>
<action dev="ggregory" type="add" due-to="Gary Gregory">Add IOIterable.asIterable().</action>
- <action dev="pkarwasz" type="add" due-to="Piotr P. Karwasz">Add CloseShieldChannel to close-shielded NIO Channels.</action>
+ <action dev="pkarwasz" type="add" due-to="Piotr P. Karwasz">Add CloseShieldChannel to close-shielded NIO Channels #786.</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 85 to 88 #774, #783.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump commons-codec:commons-codec from 1.18.0 to 1.19.0.</action>
diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
index e100082..a9a462d 100644
--- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
+++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannel.java
@@ -37,19 +37,16 @@
*/
public final class CloseShieldChannel {
- private static Class<?>[] collectChannelInterfaces(final Class<?> type) {
- final Set<Class<?>> out = new LinkedHashSet<>();
- collectChannelInterfaces(type, out);
- return out.toArray(new Class<?>[0]);
- }
+ private static final Class<?>[] EMPTY = {};
- private static void collectChannelInterfaces(final Class<?> type, final Set<Class<?>> out) {
+ private static Set<Class<?>> collectChannelInterfaces(final Class<?> type, final Set<Class<?>> out) {
// Visit interfaces
for (final Class<?> iface : type.getInterfaces()) {
if (Channel.class.isAssignableFrom(iface) && out.add(iface)) {
collectChannelInterfaces(iface, out);
}
}
+ return out;
}
/**
@@ -63,18 +60,14 @@ private static void collectChannelInterfaces(final Class<?> type, final Set<Clas
public static <T extends Channel> T wrap(final T channel) {
Objects.requireNonNull(channel, "channel");
// Fast path: already our shield
- if (Proxy.isProxyClass(channel.getClass())) {
- if (Proxy.getInvocationHandler(channel) instanceof CloseShieldChannelHandler) {
- return channel;
- }
+ if (Proxy.isProxyClass(channel.getClass()) && Proxy.getInvocationHandler(channel) instanceof CloseShieldChannelHandler) {
+ return channel;
}
// Collect only Channel sub-interfaces.
- Class<?>[] ifaces = collectChannelInterfaces(channel.getClass());
- if (ifaces.length == 0) {
- ifaces = new Class<?>[] { Channel.class }; // fallback to root surface
- }
+ final Set<Class<?>> set = collectChannelInterfaces(channel.getClass(), new LinkedHashSet<>());
+ // fallback to root surface
return (T) Proxy.newProxyInstance(channel.getClass().getClassLoader(), // use delegate's loader
- ifaces, new CloseShieldChannelHandler(channel));
+ set.isEmpty() ? new Class<?>[] { Channel.class } : set.toArray(EMPTY), new CloseShieldChannelHandler(channel));
}
private CloseShieldChannel() {
diff --git a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
index 67386e3..f13b101 100644
--- a/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
+++ b/src/main/java/org/apache/commons/io/channels/CloseShieldChannelHandler.java
@@ -103,7 +103,7 @@ public Object invoke(final Object proxy, final Method method, final Object[] arg
private Object invokeObjectMethod(final Object proxy, final Method method, final Object[] args) {
switch (method.getName()) {
case "toString":
- return "CloseShield(" + delegate + ")";
+ return "CloseShieldChannel(" + delegate + ")";
case "hashCode":
return Objects.hashCode(delegate);
case "equals": {