protocols, Class>... shouldHandleClasses) {
+ super(protocols, shouldHandleClasses);
+ }
+ @Override
+ protected URLStreamHandler createURLStreamHandlerImpl(String protocol) {
+ return new TestPlurlCopyStreamHandler(false);
+ }
+
+ @Override
+ public boolean shouldHandle(Class> clazz) {
+ return shouldHandleImpl(clazz);
+ }
+ }
+
static class CatchAllPlurlFactory extends TestURLStreamHandlerFactory implements PlurlStreamHandlerFactory {
CatchAllPlurlFactory(String... protos) {
super(Arrays.asList(protos));
@@ -281,8 +314,58 @@ public String toString() {
}
}
+ static class TestPlurlCopyStreamHandler extends org.eclipse.osgitech.plurl.test.copy.PlurlStreamHandlerBase {
+ private final boolean unsupported;
+
+ public TestPlurlCopyStreamHandler() {
+ this(false);
+ }
+
+ public TestPlurlCopyStreamHandler(boolean unsupported) {
+ this.unsupported = unsupported;
+ }
+
+ @Override
+ public URLConnection openConnection(URL u) throws IOException {
+ if (unsupported) {
+ throw new UnsupportedOperationException();
+ }
+ return new URLConnection(u) {
+ @Override
+ public String getContentType() {
+ // for testing purposes just use the test protocol name
+ return u.getProtocol();
+ }
+
+ @Override
+ public void connect() throws IOException {
+ // do nothing
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ // just testing
+ return new ByteArrayInputStream(u.getProtocol().getBytes());
+ }
+ };
+ }
+
+ @Override
+ public void parseURL(PlurlSetter setter, URL u, String spec, int start, int limit) {
+ if (unsupported) {
+ throw new UnsupportedOperationException();
+ }
+ super.parseURL(setter, u, spec, start, limit);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + '@' + System.identityHashCode(this);
+ }
+ }
+
enum TestFactoryType {
- PLURL_FACTORY, PLURL_PROXY_FACTORY, NOT_PLURL_FACTORY, LEGACY_FACTORY
+ PLURL_FACTORY, PLURL_PROXY_FACTORY, PLURL_COPY_FACTORY, NOT_PLURL_FACTORY, LEGACY_FACTORY
}
static final boolean CAN_REFLECT_SET_URL_HANDLER;
static final String CAN_REFLECT_ON_URL_STREAM_HANDLER;
@@ -375,6 +458,8 @@ static TestURLStreamHandlerFactory createTestURLStreamHandlerFactory(TestFactory
return new TestNotPlurlStreamHandlerFactory(protocols, shouldHandleClasses);
case PLURL_PROXY_FACTORY:
return createProxyURLHandlerFactory(protocols, shouldHandleClasses);
+ case PLURL_COPY_FACTORY:
+ return new TestPlurlCopyStreamHandlerFactory(protocols, shouldHandleClasses);
default:
throw new UnsupportedOperationException("Unknown type: " + type);
}
@@ -407,6 +492,8 @@ static TestContentHandlerFactory createTestContentHandlerFactory(TestFactoryType
return new TestNotPlurlContentHandlerFactory(mimetypes, shouldHandleClasses);
case PLURL_PROXY_FACTORY:
return createProxyContentFactory(mimetypes, shouldHandleClasses);
+ case PLURL_COPY_FACTORY:
+ return new TestPlurlCopyContentHandlerFactory(mimetypes, shouldHandleClasses);
default:
throw new UnsupportedOperationException("Unknown type: " + type);
}
@@ -680,7 +767,7 @@ static Field getField(Class> clazz, Class> type, boolean instance) {
}
static String canReflect(TestFactoryType type) {
- if (type == TestFactoryType.PLURL_FACTORY || type == TestFactoryType.PLURL_PROXY_FACTORY) {
+ if (type == TestFactoryType.PLURL_FACTORY || type == TestFactoryType.PLURL_PROXY_FACTORY || type == TestFactoryType.PLURL_COPY_FACTORY) {
return String.valueOf(true);
}
return PlurlTestHandlers.CAN_REFLECT_ON_URL_STREAM_HANDLER;
diff --git a/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlContentHandlerFactory.java b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlContentHandlerFactory.java
new file mode 100644
index 0000000..5e3a431
--- /dev/null
+++ b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlContentHandlerFactory.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgitech.plurl.test.copy;
+
+import java.net.ContentHandlerFactory;
+
+/**
+ * A {@link ContentHandlerFactory} that also implements {@link PlurlFactory}
+ */
+public interface PlurlContentHandlerFactory extends ContentHandlerFactory, PlurlFactory {
+ // a marker interface for a ContentHandlerFactory that implements PlurlFactory
+}
diff --git a/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlFactory.java b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlFactory.java
new file mode 100644
index 0000000..e7d2813
--- /dev/null
+++ b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlFactory.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgitech.plurl.test.copy;
+
+
+public interface PlurlFactory {
+
+ boolean shouldHandle(Class> clazz);
+}
diff --git a/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandler.java b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandler.java
new file mode 100644
index 0000000..c7f8d33
--- /dev/null
+++ b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandler.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgitech.plurl.test.copy;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+
+
+public interface PlurlStreamHandler {
+
+ public interface PlurlSetter {
+
+ public void setURL(URL u, String protocol, String host, int port, String authority, String userInfo,
+ String path, String query, String ref);
+ }
+
+ public boolean equals(URL u1, URL u2);
+
+ public int hashCode(URL u);
+
+ public boolean hostsEqual(URL u1, URL u2);
+
+ public int getDefaultPort();
+
+ public InetAddress getHostAddress(URL u);
+
+ public URLConnection openConnection(URL u) throws IOException;
+
+ public URLConnection openConnection(URL u, Proxy p) throws IOException;
+
+ public boolean sameFile(URL u1, URL u2);
+
+ public String toExternalForm(URL u);
+
+ public void parseURL(PlurlSetter plurlSetter, URL u, String spec, int start, int limit);
+
+ public void setURL(URL u, String proto, String host, int port, String file, String ref);
+
+ public void setURL(URL u, String proto, String host, int port, String auth, String user, String path,
+ String query, String ref);
+}
diff --git a/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerBase.java b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerBase.java
new file mode 100644
index 0000000..b98b8e9
--- /dev/null
+++ b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerBase.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgitech.plurl.test.copy;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+public abstract class PlurlStreamHandlerBase extends URLStreamHandler implements PlurlStreamHandler {
+ private volatile PlurlSetter plurlSetter;
+
+ @Override
+ public abstract URLConnection openConnection(URL u) throws IOException;
+
+ @Override
+ public void parseURL(PlurlSetter setter, URL u, String spec, int start, int limit) {
+ this.plurlSetter = setter;
+ parseURL(u, spec, start, limit);
+ }
+
+ @Override
+ public URLConnection openConnection(URL u, Proxy p) throws IOException {
+ return super.openConnection(u, p);
+ }
+
+ @Override
+ public String toExternalForm(URL u) {
+ return super.toExternalForm(u);
+ }
+
+ @Override
+ public boolean equals(URL u1, URL u2) {
+ return super.equals(u1, u2);
+ }
+
+ @Override
+ public int getDefaultPort() {
+ return super.getDefaultPort();
+ }
+
+ @Override
+ public InetAddress getHostAddress(URL u) {
+ return super.getHostAddress(u);
+ }
+
+ @Override
+ public int hashCode(URL u) {
+ return super.hashCode(u);
+ }
+
+ @Override
+ public boolean hostsEqual(URL u1, URL u2) {
+ return super.hostsEqual(u1, u2);
+ }
+
+ @Override
+ public boolean sameFile(URL u1, URL u2) {
+ return super.sameFile(u1, u2);
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void setURL(URL u, String proto, String host, int port, String file, String ref) {
+ PlurlSetter current = plurlSetter;
+ if (current == null) {
+ // something is calling the handler directly, probably passed it to URL directly
+ super.setURL(u, proto, host, port, null, null, file, null, ref);
+ } else {
+ current.setURL(u, proto, host, port, null, null, file, null, ref);
+ }
+ }
+
+ @Override
+ public void setURL(URL u, String proto, String host, int port, String auth, String user, String path,
+ String query, String ref) {
+ PlurlSetter current = plurlSetter;
+ if (current == null) {
+ // something is calling the handler directly, probably passed it to URL directly
+ super.setURL(u, proto, host, port, auth, user, path, query, ref);
+ } else {
+ current.setURL(u, proto, host, port, auth, user, path, query, ref);
+ }
+ }
+
+}
diff --git a/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerFactory.java b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerFactory.java
new file mode 100644
index 0000000..52619ab
--- /dev/null
+++ b/src/test/java/org/eclipse/osgitech/plurl/test/copy/PlurlStreamHandlerFactory.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2025 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgitech.plurl.test.copy;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * A {@link URLStreamHandlerFactory} that also implements {@link PlurlFactory}
+ */
+public interface PlurlStreamHandlerFactory extends URLStreamHandlerFactory, PlurlFactory {
+
+ /**
+ * A factory is expected to return {@link URLStreamHandler} instances that also
+ * implement {@link PlurlStreamHandler}. If the returned handler does not
+ * implement {@link PlurlStreamHandler} then deep reflection is required and the
+ * JVM may require the "--add-opens" option in order to open the "java.net"
+ * package for reflection. For example:
+ *
+ *
+ * --add-opens java.base/java.net=ALL-UNNAMED
+ *
+ *
+ * @see URLStreamHandlerFactory#createURLStreamHandler(String)
+ */
+ @Override
+ URLStreamHandler createURLStreamHandler(String protocol);
+}