org.eclipse.osgi.internal.url.URLStreamHandlerProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2003, 2016 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.osgi.internal.url;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
import org.osgi.framework.*;
import org.osgi.service.url.URLConstants;
import org.osgi.service.url.URLStreamHandlerService;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* The URLStreamHandlerProxy is a URLStreamHandler that acts as a proxy for registered
* URLStreamHandlerServices. When a URLStreamHandler is requested from the URLStreamHandlerFactory
* and it exists in the service registry, a URLStreamHandlerProxy is created which will pass all the
* requests from the requestor to the real URLStreamHandlerService. We can't return the real
* URLStreamHandlerService from the URLStreamHandlerFactory because the JVM caches URLStreamHandlers
* and therefore would not support a dynamic environment of URLStreamHandlerServices being registered
* and unregistered.
*/
public class URLStreamHandlerProxy extends URLStreamHandler implements ServiceTrackerCustomizer> {
// TODO lots of type-based names
protected URLStreamHandlerService realHandlerService;
protected URLStreamHandlerSetter urlSetter;
protected ServiceTracker> urlStreamHandlerServiceTracker;
protected BundleContext context;
protected ServiceReference urlStreamServiceReference;
protected String protocol;
protected int ranking = Integer.MIN_VALUE;
public URLStreamHandlerProxy(String protocol, ServiceReference reference, BundleContext context) {
this.context = context;
this.protocol = protocol;
urlSetter = new URLStreamHandlerSetter(this);
//set the handler and ranking
setNewHandler(reference, getRank(reference));
urlStreamHandlerServiceTracker = new ServiceTracker<>(context, URLStreamHandlerFactoryImpl.URLSTREAMHANDLERCLASS, this);
URLStreamHandlerFactoryImpl.secureAction.open(urlStreamHandlerServiceTracker);
}
private void setNewHandler(ServiceReference reference, int rank) {
if (urlStreamServiceReference != null)
context.ungetService(urlStreamServiceReference);
urlStreamServiceReference = reference;
ranking = rank;
if (reference == null)
realHandlerService = new NullURLStreamHandlerService();
else
realHandlerService = URLStreamHandlerFactoryImpl.secureAction.getService(reference, context);
}
/**
* @see java.net.URLStreamHandler#equals(URL, URL)
*/
@Override
protected boolean equals(URL url1, URL url2) {
return realHandlerService.equals(url1, url2);
}
/**
* @see java.net.URLStreamHandler#getDefaultPort()
*/
@Override
protected int getDefaultPort() {
return realHandlerService.getDefaultPort();
}
/**
* @see java.net.URLStreamHandler#getHostAddress(URL)
*/
@Override
protected InetAddress getHostAddress(URL url) {
return realHandlerService.getHostAddress(url);
}
/**
* @see java.net.URLStreamHandler#hashCode(URL)
*/
@Override
protected int hashCode(URL url) {
return realHandlerService.hashCode(url);
}
/**
* @see java.net.URLStreamHandler#hostsEqual(URL, URL)
*/
@Override
protected boolean hostsEqual(URL url1, URL url2) {
return realHandlerService.hostsEqual(url1, url2);
}
/**
* @see java.net.URLStreamHandler#openConnection(URL)
*/
@Override
protected URLConnection openConnection(URL url) throws IOException {
return realHandlerService.openConnection(url);
}
/**
* @see java.net.URLStreamHandler#parseURL(URL, String, int, int)
*/
@Override
protected void parseURL(URL url, String str, int start, int end) {
realHandlerService.parseURL(urlSetter, url, str, start, end);
}
/**
* @see java.net.URLStreamHandler#sameFile(URL, URL)
*/
@Override
protected boolean sameFile(URL url1, URL url2) {
return realHandlerService.sameFile(url1, url2);
}
/**
* @see java.net.URLStreamHandler#toExternalForm(URL)
*/
@Override
protected String toExternalForm(URL url) {
return realHandlerService.toExternalForm(url);
}
/**
* @see java.net.URLStreamHandler#setURL(URL, String, String, int, String, String, String, String, String)
*/
@Override
public void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String file, String query, String ref) {
super.setURL(u, protocol, host, port, authority, userInfo, file, query, ref);
}
@SuppressWarnings("deprecation")
@Override
public void setURL(URL url, String protocol, String host, int port, String file, String ref) {
//using non-deprecated URLStreamHandler.setURL method.
//setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String file, String query, String ref)
super.setURL(url, protocol, host, port, null, null, file, null, ref);
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(ServiceReference)
*/
@Override
public ServiceReference addingService(ServiceReference reference) {
//check to see if our protocol is being registered by another service
Object prop = reference.getProperty(URLConstants.URL_HANDLER_PROTOCOL);
if (prop instanceof String) {
prop = new String[] {(String) prop};
}
if (!(prop instanceof String[])) {
return null;
}
String[] protocols = (String[]) prop;
for (String candidateProtocol : protocols) {
if (candidateProtocol.equals(protocol)) {
//If our protocol is registered by another service, check the service ranking and switch URLStreamHandlers if nessecary.
int newServiceRanking = getRank(reference);
if (newServiceRanking > ranking || urlStreamServiceReference == null)
setNewHandler(reference, newServiceRanking);
return reference;
}
}
//we don't want to continue hearing events about a URLStreamHandlerService not registered under our protocol
return null;
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
*/
// check to see if the ranking has changed. If so, re-select a new URLHandler
@Override
public void modifiedService(ServiceReference reference, ServiceReference service) {
int newRank = getRank(reference);
if (reference == urlStreamServiceReference) {
if (newRank < ranking) {
// The URLHandler we are currently using has dropped it's ranking below a URLHandler registered
// for the same protocol. We need to swap out URLHandlers.
// this should get us the highest ranked service, if available
ServiceReference newReference = urlStreamHandlerServiceTracker.getServiceReference();
if (newReference != urlStreamServiceReference && newReference != null) {
setNewHandler(newReference, ((Integer) newReference.getProperty(Constants.SERVICE_RANKING)).intValue());
}
}
} else if (newRank > ranking) {
// the service changed is another URLHandler that we are not currently using
// If it's ranking is higher, we must swap it in.
setNewHandler(reference, newRank);
}
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(ServiceReference, Object)
*/
@Override
public void removedService(ServiceReference reference, ServiceReference service) {
// check to see if our URLStreamHandler was unregistered.
if (reference != urlStreamServiceReference)
return;
// If so, look for a lower ranking URLHandler
// this should get us the highest ranking service left, if available
ServiceReference newReference = urlStreamHandlerServiceTracker.getServiceReference();
// if newReference == null then we will use the NullURLStreamHandlerService here
setNewHandler(newReference, getRank(newReference));
}
private int getRank(ServiceReference> reference) {
if (reference == null)
return Integer.MIN_VALUE;
Object property = reference.getProperty(Constants.SERVICE_RANKING);
return (property instanceof Integer) ? ((Integer) property).intValue() : 0;
}
@Override
protected URLConnection openConnection(URL u, Proxy p) throws IOException {
try {
Method openConn = realHandlerService.getClass().getMethod("openConnection", new Class[] {URL.class, Proxy.class}); //$NON-NLS-1$
openConn.setAccessible(true);
return (URLConnection) openConn.invoke(realHandlerService, new Object[] {u, p});
} catch (InvocationTargetException e) {
if (e.getTargetException() instanceof IOException)
throw (IOException) e.getTargetException();
throw (RuntimeException) e.getTargetException();
} catch (Exception e) {
// expected on JRE < 1.5
throw new UnsupportedOperationException(e);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy