| /* |
| * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.xml.internal.ws.api; |
| |
| import com.sun.istack.internal.Nullable; |
| |
| import javax.xml.ws.WebServiceException; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.Proxy; |
| import java.net.ProxySelector; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.net.URLStreamHandler; |
| import java.util.Iterator; |
| |
| /** |
| * Represents the endpoint address URI. |
| * |
| * <p> |
| * Conceptually this can be really thought of as an {@link URI}, |
| * but it hides some of the details that improve the performance. |
| * |
| * <p> |
| * Being an {@link URI} allows this class to represent custom made-up URIs |
| * (like "jms" for example.) Whenever possible, this object |
| * also creates an {@link URL} (this is only possible when the address |
| * has a registered {@link URLStreamHandler}), so that if the clients |
| * of this code wants to use it, it can do so. |
| * |
| * |
| * <h3>How it improves the performance</h3> |
| * <ol> |
| * <li> |
| * Endpoint address is often eventually turned into an {@link URLConnection}, |
| * and given that generally this value is read more often than being set, |
| * it makes sense to eagerly turn it into an {@link URL}, |
| * thereby avoiding a repeated conversion. |
| * |
| * <li> |
| * JDK spends a lot of time choosing a list of {@link Proxy} |
| * to connect to an {@link URL}. Since the default proxy selector |
| * implementation always return the same proxy for the same URL, |
| * we can determine the proxy by ourselves to let JDK skip its |
| * proxy-discovery step. |
| * |
| * (That said, user-defined proxy selector can do a lot of interesting things |
| * --- like doing a round-robin, or pick one from a proxy farm randomly, |
| * and so it's dangerous to stick to one proxy. For this case, |
| * we still let JDK decide the proxy. This shouldn't be that much of an |
| * disappointment, since most people only mess with system properties, |
| * and never with {@link ProxySelector}. Also, avoiding optimization |
| * with non-standard proxy selector allows people to effectively disable |
| * this optimization, which may come in handy for a trouble-shooting.) |
| * </ol> |
| * |
| * @author Kohsuke Kawaguchi |
| */ |
| public final class EndpointAddress { |
| @Nullable |
| private URL url; |
| private final URI uri; |
| private final String stringForm; |
| private volatile boolean dontUseProxyMethod; |
| /** |
| * Pre-selected proxy. |
| * |
| * If {@link #url} is null, this field is null. |
| * Otherwise, this field could still be null if the proxy couldn't be chosen |
| * upfront. |
| */ |
| private Proxy proxy; |
| |
| public EndpointAddress(URI uri) { |
| this.uri = uri; |
| this.stringForm = uri.toString(); |
| try { |
| initURL(); |
| proxy = chooseProxy(); |
| } catch (MalformedURLException e) { |
| // ignore |
| } |
| } |
| |
| /** |
| * |
| * @see #create(String) |
| */ |
| public EndpointAddress(String url) throws URISyntaxException { |
| this.uri = new URI(url); |
| this.stringForm = url; |
| try { |
| initURL(); |
| proxy = chooseProxy(); |
| } catch (MalformedURLException e) { |
| // ignore |
| } |
| } |
| |
| |
| private void initURL() throws MalformedURLException { |
| String scheme = uri.getScheme(); |
| //URI.toURL() only works when scheme is not null. |
| if (scheme == null) { |
| this.url = new URL(uri.toString()); |
| return; |
| } |
| scheme =scheme.toLowerCase(); |
| if ("http".equals(scheme) || "https".equals(scheme)) { |
| url = new URL(uri.toASCIIString()); |
| } else { |
| this.url = uri.toURL(); |
| } |
| } |
| |
| /** |
| * Creates a new {@link EndpointAddress} with a reasonably |
| * generic error handling. |
| */ |
| public static EndpointAddress create(String url) { |
| try { |
| return new EndpointAddress(url); |
| } catch(URISyntaxException e) { |
| throw new WebServiceException("Illegal endpoint address: "+url,e); |
| } |
| } |
| |
| private Proxy chooseProxy() { |
| ProxySelector sel = |
| java.security.AccessController.doPrivileged( |
| new java.security.PrivilegedAction<ProxySelector>() { |
| @Override |
| public ProxySelector run() { |
| return ProxySelector.getDefault(); |
| } |
| }); |
| |
| if(sel==null) |
| return Proxy.NO_PROXY; |
| |
| |
| if(!sel.getClass().getName().equals("sun.net.spi.DefaultProxySelector")) |
| // user-defined proxy. may return a different proxy for each invocation |
| return null; |
| |
| Iterator<Proxy> it = sel.select(uri).iterator(); |
| if(it.hasNext()) |
| return it.next(); |
| |
| return Proxy.NO_PROXY; |
| } |
| |
| /** |
| * Returns an URL of this endpoint adress. |
| * |
| * @return |
| * null if this endpoint address doesn't have a registered {@link URLStreamHandler}. |
| */ |
| public URL getURL() { |
| return url; |
| } |
| |
| /** |
| * Returns an URI of the endpoint address. |
| * |
| * @return |
| * always non-null. |
| */ |
| public URI getURI() { |
| return uri; |
| } |
| |
| /** |
| * Tries to open {@link URLConnection} for this endpoint. |
| * |
| * <p> |
| * This is possible only when an endpoint address has |
| * the corresponding {@link URLStreamHandler}. |
| * |
| * @throws IOException |
| * if {@link URL#openConnection()} reports an error. |
| * @throws AssertionError |
| * if this endpoint doesn't have an associated URL. |
| * if the code is written correctly this shall never happen. |
| */ |
| public URLConnection openConnection() throws IOException { |
| if (url == null) { |
| throw new WebServiceException("URI="+uri+" doesn't have the corresponding URL"); |
| } |
| if(proxy!=null && !dontUseProxyMethod) { |
| try { |
| return url.openConnection(proxy); |
| } catch(UnsupportedOperationException e) { |
| // Some OSGi and app server environments donot |
| // override URLStreamHandler.openConnection(URL, Proxy) as it |
| // is introduced in Java SE 5 API. Fallback to the other method. |
| dontUseProxyMethod = true; |
| } |
| } |
| return url.openConnection(); |
| } |
| |
| @Override |
| public String toString() { |
| return stringForm; |
| } |
| } |