1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/transport/http/HttpAdapterList.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,156 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.ws.transport.http; 1.30 + 1.31 +import com.sun.xml.internal.ws.transport.http.DeploymentDescriptorParser.AdapterFactory; 1.32 +import com.sun.xml.internal.ws.api.server.WSEndpoint; 1.33 +import com.sun.xml.internal.ws.api.server.PortAddressResolver; 1.34 +import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 1.35 +import com.sun.istack.internal.NotNull; 1.36 + 1.37 +import javax.xml.namespace.QName; 1.38 +import java.util.List; 1.39 +import java.util.ArrayList; 1.40 +import java.util.Map; 1.41 +import java.util.HashMap; 1.42 +import java.util.AbstractList; 1.43 +import java.util.Map.Entry; 1.44 + 1.45 +/** 1.46 + * List of {@link HttpAdapter}s created together. 1.47 + * 1.48 + * <p> 1.49 + * Some cases WAR file may contain multiple endpoints for ports in a WSDL. 1.50 + * If the runtime knows these ports, their port addresses can be patched. 1.51 + * This class keeps a list of {@link HttpAdapter}s and use that information to patch 1.52 + * multiple port addresses. 1.53 + * 1.54 + * <p> 1.55 + * Concrete implementations of this class need to override {@link #createHttpAdapter} 1.56 + * method to create implementations of {@link HttpAdapter}. 1.57 + * 1.58 + * @author Jitendra Kotamraju 1.59 + */ 1.60 +public abstract class HttpAdapterList<T extends HttpAdapter> extends AbstractList<T> implements AdapterFactory<T> { 1.61 + private final List<T> adapters = new ArrayList<T>(); 1.62 + private final Map<PortInfo, String> addressMap = new HashMap<PortInfo, String>(); 1.63 + 1.64 + // TODO: documented because it's used by AS 1.65 + @Override 1.66 + public T createAdapter(String name, String urlPattern, WSEndpoint<?> endpoint) { 1.67 + T t = createHttpAdapter(name, urlPattern, endpoint); 1.68 + adapters.add(t); 1.69 + WSDLPort port = endpoint.getPort(); 1.70 + if (port != null) { 1.71 + PortInfo portInfo = new PortInfo(port.getOwner().getName(),port.getName().getLocalPart(), endpoint.getImplementationClass()); 1.72 + addressMap.put(portInfo, getValidPath(urlPattern)); 1.73 + } 1.74 + return t; 1.75 + } 1.76 + 1.77 + /** 1.78 + * Implementations need to override this one to create a concrete class 1.79 + * of HttpAdapter 1.80 + */ 1.81 + protected abstract T createHttpAdapter(String name, String urlPattern, WSEndpoint<?> endpoint); 1.82 + 1.83 + /** 1.84 + * @return urlPattern without "/*" 1.85 + */ 1.86 + private String getValidPath(@NotNull String urlPattern) { 1.87 + if (urlPattern.endsWith("/*")) { 1.88 + return urlPattern.substring(0, urlPattern.length() - 2); 1.89 + } else { 1.90 + return urlPattern; 1.91 + } 1.92 + } 1.93 + 1.94 + /** 1.95 + * Creates a PortAddressResolver that maps portname to its address 1.96 + * 1.97 + * @param endpointImpl application endpoint Class that eventually serves the request. 1.98 + */ 1.99 + public PortAddressResolver createPortAddressResolver(final String baseAddress, final Class<?> endpointImpl) { 1.100 + return new PortAddressResolver() { 1.101 + @Override 1.102 + public String getAddressFor(@NotNull QName serviceName, @NotNull String portName) { 1.103 + String urlPattern = addressMap.get(new PortInfo(serviceName,portName, endpointImpl)); 1.104 + if (urlPattern == null) { 1.105 + //if a WSDL defines more ports, urlpattern is null (portName does not match endpointImpl) 1.106 + //so fallback to the default behaviour where only serviceName/portName is checked 1.107 + for (Entry<PortInfo, String> e : addressMap.entrySet()) { 1.108 + if (serviceName.equals(e.getKey().serviceName) && portName.equals(e.getKey().portName)) { 1.109 + urlPattern = e.getValue(); 1.110 + break; 1.111 + } 1.112 + } 1.113 + } 1.114 + return (urlPattern == null) ? null : baseAddress+urlPattern; 1.115 + } 1.116 + }; 1.117 + } 1.118 + 1.119 + 1.120 + @Override 1.121 + public T get(int index) { 1.122 + return adapters.get(index); 1.123 + } 1.124 + 1.125 + @Override 1.126 + public int size() { 1.127 + return adapters.size(); 1.128 + } 1.129 + 1.130 + private static class PortInfo { 1.131 + private final QName serviceName; 1.132 + private final String portName; 1.133 + private final Class<?> implClass; 1.134 + 1.135 + PortInfo(@NotNull QName serviceName, @NotNull String portName, Class<?> implClass) { 1.136 + this.serviceName = serviceName; 1.137 + this.portName = portName; 1.138 + this.implClass = implClass; 1.139 + } 1.140 + 1.141 + @Override 1.142 + public boolean equals(Object portInfo) { 1.143 + if (portInfo instanceof PortInfo) { 1.144 + PortInfo that = (PortInfo)portInfo; 1.145 + if (this.implClass == null) { 1.146 + return this.serviceName.equals(that.serviceName) && this.portName.equals(that.portName) && that.implClass == null; 1.147 + } 1.148 + return this.serviceName.equals(that.serviceName) && this.portName.equals(that.portName) && this.implClass.equals(that.implClass); 1.149 + } 1.150 + return false; 1.151 + } 1.152 + 1.153 + @Override 1.154 + public int hashCode() { 1.155 + int retVal = serviceName.hashCode()+portName.hashCode(); 1.156 + return implClass != null ? retVal + implClass.hashCode() : retVal; 1.157 + } 1.158 + } 1.159 +}