/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG 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 * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.communication.core.proxyselector; import java.io.Closeable; import java.io.IOException; import java.net.Proxy; import java.net.ProxySelector; import java.net.SocketAddress; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.Assert; import org.eclipse.riena.core.util.IOUtils; /** * The {@code CompoundProxySelector} gathers all the proxies from the given {@code ProxySelector}s from the list given at instance creation. */ public class CompoundProxySelector extends ProxySelector { private final List<ProxySelector> proxySelectors; private final Set<Proxy> failedProxies = Collections.synchronizedSet(new LinkedHashSet<Proxy>()); /** * The * * @param proxySelectors */ public CompoundProxySelector(final List<ProxySelector> proxySelectors) { Assert.isLegal(proxySelectors != null, "proxySelectors must not be null."); //$NON-NLS-1$ this.proxySelectors = proxySelectors; } @Override public List<Proxy> select(final URI uri) { Assert.isLegal(uri != null, "uri must not be null."); //$NON-NLS-1$ final List<Proxy> result = new ArrayList<Proxy>(); for (final ProxySelector proxySelector : proxySelectors) { final List<Proxy> proxies = proxySelector.select(uri); if (proxies == null || proxies.size() == 0) { continue; } // we do not copy NO_PROXY entries because a NO_PROXY stops the loop // within {@code java.net.SocksSocketImpl.connect(SocketAddress, int)} // instead we add a final NO_PROXY to the end of the list (see below) for (final Proxy proxy : proxies) { if (proxy != Proxy.NO_PROXY && !result.contains(proxy)) { result.add(proxy); } } } // in case we have �failed proxies� we move them towards the end of the list ProxySelectorUtils.resort(result, failedProxies); // add a final NO_PROXY result.add(Proxy.NO_PROXY); return result; } @Override public void connectFailed(final URI uri, final SocketAddress sa, final IOException ioe) { // we �resort� the resulted proxy list by moving the failed proxies to the end of the list (see select) ... final Proxy failed = ProxySelectorUtils.createProxy(uri.getScheme(), sa); failedProxies.add(failed); // ... and additionally delegate it to all proxy selectors so that they can do their job. // This assumes that they can deal with failed proxies they have not delivered. for (final ProxySelector proxySelector : proxySelectors) { proxySelector.connectFailed(uri, sa, ioe); } } public void uninstall() { // Check for ProxySelectors that implement the optional Closeable interface and close them. for (final ProxySelector proxySelector : proxySelectors) { if (proxySelector instanceof Closeable) { IOUtils.close((Closeable) proxySelector); } } } }