001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.transport.http;
038:
039: import com.sun.xml.ws.transport.http.DeploymentDescriptorParser.AdapterFactory;
040: import com.sun.xml.ws.api.server.WSEndpoint;
041: import com.sun.xml.ws.api.server.PortAddressResolver;
042: import com.sun.xml.ws.api.model.wsdl.WSDLPort;
043: import com.sun.istack.NotNull;
044:
045: import javax.xml.namespace.QName;
046: import java.util.List;
047: import java.util.ArrayList;
048: import java.util.Map;
049: import java.util.HashMap;
050: import java.util.AbstractList;
051:
052: /**
053: * List of {@link HttpAdapter}s created together.
054: *
055: * <p>
056: * Some cases WAR file may contain multiple endpoints for ports in a WSDL.
057: * If the runtime knows these ports, their port addresses can be patched.
058: * This class keeps a list of {@link HttpAdapter}s and use that information to patch
059: * multiple port addresses.
060: *
061: * <p>
062: * Concrete implementations of this class need to override {@link #createHttpAdapter}
063: * method to create implementations of {@link HttpAdapter}.
064: *
065: * @author Jitendra Kotamraju
066: */
067: public abstract class HttpAdapterList<T extends HttpAdapter> extends
068: AbstractList<T> implements AdapterFactory<T> {
069: private final List<T> adapters = new ArrayList<T>();
070: private final Map<PortInfo, String> addressMap = new HashMap<PortInfo, String>();
071:
072: // TODO: documented because it's used by AS
073: public T createAdapter(String name, String urlPattern,
074: WSEndpoint<?> endpoint) {
075: T t = createHttpAdapter(name, urlPattern, endpoint);
076: adapters.add(t);
077: WSDLPort port = endpoint.getPort();
078: if (port != null) {
079: PortInfo portInfo = new PortInfo(port.getOwner().getName(),
080: port.getName().getLocalPart());
081: addressMap.put(portInfo, getValidPath(urlPattern));
082: }
083: return t;
084: }
085:
086: /**
087: * Implementations need to override this one to create a concrete class
088: * of HttpAdapter
089: */
090: protected abstract T createHttpAdapter(String name,
091: String urlPattern, WSEndpoint<?> endpoint);
092:
093: /**
094: * @return urlPattern without "/*"
095: */
096: private String getValidPath(@NotNull
097: String urlPattern) {
098: if (urlPattern.endsWith("/*")) {
099: return urlPattern.substring(0, urlPattern.length() - 2);
100: } else {
101: return urlPattern;
102: }
103: }
104:
105: /**
106: * Creates a PortAddressResolver that maps portname to its address
107: */
108: public PortAddressResolver createPortAddressResolver(
109: final String baseAddress) {
110: return new PortAddressResolver() {
111: public String getAddressFor(@NotNull
112: QName serviceName, @NotNull
113: String portName) {
114: String urlPattern = addressMap.get(new PortInfo(
115: serviceName, portName));
116: return (urlPattern == null) ? null : baseAddress
117: + urlPattern;
118: }
119: };
120: }
121:
122: public T get(int index) {
123: return adapters.get(index);
124: }
125:
126: public int size() {
127: return adapters.size();
128: }
129:
130: private static class PortInfo {
131: private final QName serviceName;
132: private final String portName;
133:
134: PortInfo(@NotNull
135: QName serviceName, @NotNull
136: String portName) {
137: this .serviceName = serviceName;
138: this .portName = portName;
139: }
140:
141: @Override
142: public boolean equals(Object portInfo) {
143: if (portInfo instanceof PortInfo) {
144: PortInfo that = (PortInfo) portInfo;
145: return this .serviceName.equals(that.serviceName)
146: && this .portName.equals(that.portName);
147: }
148: return false;
149: }
150:
151: @Override
152: public int hashCode() {
153: return serviceName.hashCode() + portName.hashCode();
154: }
155: }
156: }
|