/******************************************************************************* * Copyright (c) 2006, 2016 Cognos Incorporated, IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * *******************************************************************************/ package org.eclipse.osgi.internal.url; import java.io.IOException; import java.lang.reflect.*; import java.net.*; import java.net.Proxy; import org.eclipse.osgi.framework.log.FrameworkLogEntry; public class MultiplexingURLStreamHandler extends URLStreamHandler { private static Method openConnectionMethod; private static Method openConnectionProxyMethod; private static Method equalsMethod; private static Method getDefaultPortMethod; private static Method getHostAddressMethod; private static Method hashCodeMethod; private static Method hostsEqualMethod; private static Method parseURLMethod; private static Method sameFileMethod; private static Method setURLMethod; private static Method toExternalFormMethod; private static Field handlerField; private static boolean methodsInitialized = false; private String protocol; private URLStreamHandlerFactoryImpl factory; private final URLStreamHandler authorized; private static synchronized void initializeMethods(URLStreamHandlerFactoryImpl factory) { if (methodsInitialized) return; try { openConnectionMethod = URLStreamHandler.class.getDeclaredMethod("openConnection", new Class[] {URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(openConnectionMethod); openConnectionProxyMethod = URLStreamHandler.class.getDeclaredMethod("openConnection", new Class[] {URL.class, Proxy.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(openConnectionProxyMethod); equalsMethod = URLStreamHandler.class.getDeclaredMethod("equals", new Class[] {URL.class, URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(equalsMethod); getDefaultPortMethod = URLStreamHandler.class.getDeclaredMethod("getDefaultPort", (Class[]) null); //$NON-NLS-1$ MultiplexingFactory.setAccessible(getDefaultPortMethod); getHostAddressMethod = URLStreamHandler.class.getDeclaredMethod("getHostAddress", new Class[] {URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(getHostAddressMethod); hashCodeMethod = URLStreamHandler.class.getDeclaredMethod("hashCode", new Class[] {URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(hashCodeMethod); hostsEqualMethod = URLStreamHandler.class.getDeclaredMethod("hostsEqual", new Class[] {URL.class, URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(hostsEqualMethod); parseURLMethod = URLStreamHandler.class.getDeclaredMethod("parseURL", new Class[] {URL.class, String.class, Integer.TYPE, Integer.TYPE}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(parseURLMethod); sameFileMethod = URLStreamHandler.class.getDeclaredMethod("sameFile", new Class[] {URL.class, URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(sameFileMethod); setURLMethod = URLStreamHandler.class.getDeclaredMethod("setURL", new Class[] {URL.class, String.class, String.class, Integer.TYPE, String.class, String.class, String.class, String.class, String.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(setURLMethod); toExternalFormMethod = URLStreamHandler.class.getDeclaredMethod("toExternalForm", new Class[] {URL.class}); //$NON-NLS-1$ MultiplexingFactory.setAccessible(toExternalFormMethod); try { handlerField = URL.class.getDeclaredField("handler"); //$NON-NLS-1$ } catch (NoSuchFieldException e) { handlerField = EquinoxFactoryManager.getField(URL.class, URLStreamHandler.class, true); if (handlerField == null) throw e; } MultiplexingFactory.setAccessible(handlerField); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "initializeMethods", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } methodsInitialized = true; } public MultiplexingURLStreamHandler(String protocol, URLStreamHandlerFactoryImpl factory, URLStreamHandler authorized) { this.protocol = protocol; this.factory = factory; this.authorized = authorized; initializeMethods(factory); } protected URLConnection openConnection(URL url) throws IOException { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return (URLConnection) openConnectionMethod.invoke(handler, new Object[] {url}); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof IOException) throw (IOException) e.getTargetException(); throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "openConnection", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new MalformedURLException(); } @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return (URLConnection) openConnectionProxyMethod.invoke(handler, new Object[] {url, proxy}); } catch (InvocationTargetException e) { if (e.getTargetException() instanceof IOException) throw (IOException) e.getTargetException(); throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "openConnection", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new MalformedURLException(); } protected boolean equals(URL url1, URL url2) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return ((Boolean) equalsMethod.invoke(handler, new Object[] {url1, url2})).booleanValue(); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "equals", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected int getDefaultPort() { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return ((Integer) getDefaultPortMethod.invoke(handler, (Object[]) null)).intValue(); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "getDefaultPort", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected InetAddress getHostAddress(URL url) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return (InetAddress) getHostAddressMethod.invoke(handler, new Object[] {url}); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "hashCode", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected int hashCode(URL url) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return ((Integer) hashCodeMethod.invoke(handler, new Object[] {url})).intValue(); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "hashCode", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected boolean hostsEqual(URL url1, URL url2) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return ((Boolean) hostsEqualMethod.invoke(handler, new Object[] {url1, url2})).booleanValue(); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "hostsEqual", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected void parseURL(URL arg0, String arg1, int arg2, int arg3) { URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { // set the real handler for the URL handlerField.set(arg0, handler); parseURLMethod.invoke(handler, new Object[] {arg0, arg1, Integer.valueOf(arg2), Integer.valueOf(arg3)}); return; } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "parseURL", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected boolean sameFile(URL url1, URL url2) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return ((Boolean) sameFileMethod.invoke(handler, new Object[] {url1, url2})).booleanValue(); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "sameFile", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected void setURL(URL arg0, String arg1, String arg2, int arg3, String arg4, String arg5, String arg6, String arg7, String arg8) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { // set the real handler for the URL handlerField.set(arg0, handler); setURLMethod.invoke(handler, new Object[] {arg0, arg1, arg2, Integer.valueOf(arg3), arg4, arg5, arg6, arg7, arg8}); return; } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "setURL", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } protected String toExternalForm(URL url) { URLStreamHandler handler = findAuthorizedURLStreamHandler(protocol); if (handler != null) { try { return (String) toExternalFormMethod.invoke(handler, new Object[] {url}); } catch (InvocationTargetException e) { throw (RuntimeException) e.getTargetException(); } catch (Exception e) { factory.container.getLogServices().log(MultiplexingURLStreamHandler.class.getName(), FrameworkLogEntry.ERROR, "toExternalForm", e); //$NON-NLS-1$ throw new RuntimeException(e.getMessage(), e); } } throw new IllegalStateException(); } private URLStreamHandler findAuthorizedURLStreamHandler(String requested) { URLStreamHandler handler = factory.findAuthorizedURLStreamHandler(requested); return handler == null ? authorized : handler; } }