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.servlet;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.xml.ws.api.message.Packet;
041: import com.sun.xml.ws.api.server.PortAddressResolver;
042: import com.sun.xml.ws.api.server.WSEndpoint;
043: import com.sun.xml.ws.api.server.WebServiceContextDelegate;
044: import com.sun.xml.ws.resources.WsservletMessages;
045: import com.sun.xml.ws.transport.Headers;
046: import com.sun.xml.ws.transport.http.HttpAdapter;
047: import com.sun.xml.ws.transport.http.WSHTTPConnection;
048: import com.sun.xml.ws.developer.JAXWSProperties;
049:
050: import javax.servlet.ServletContext;
051: import javax.servlet.http.HttpServlet;
052: import javax.servlet.http.HttpServletRequest;
053: import javax.servlet.http.HttpServletResponse;
054: import javax.xml.ws.WebServiceException;
055: import javax.xml.ws.handler.MessageContext;
056: import java.io.IOException;
057: import java.io.InputStream;
058: import java.io.OutputStream;
059: import java.security.Principal;
060: import java.util.ArrayList;
061: import java.util.Enumeration;
062: import java.util.List;
063: import java.util.Map;
064:
065: /**
066: *{@link WSHTTPConnection} implemented for {@link HttpServlet}.
067: *
068: * @author WS Development Team
069: */
070: final class ServletConnectionImpl extends WSHTTPConnection implements
071: WebServiceContextDelegate {
072:
073: private final HttpServletRequest request;
074: private final HttpServletResponse response;
075: private final ServletContext context;
076: private int status;
077: private Headers requestHeaders;
078: private final HttpAdapter adapter;
079:
080: public ServletConnectionImpl(@NotNull
081: HttpAdapter adapter, ServletContext context,
082: HttpServletRequest request, HttpServletResponse response) {
083: this .adapter = adapter;
084: this .context = context;
085: this .request = request;
086: this .response = response;
087: }
088:
089: @Override
090: @Property({MessageContext.HTTP_REQUEST_HEADERS,Packet.INBOUND_TRANSPORT_HEADERS})
091: public @NotNull
092: Map<String, List<String>> getRequestHeaders() {
093: if (requestHeaders == null) {
094: requestHeaders = new Headers();
095: Enumeration enums = request.getHeaderNames();
096: while (enums.hasMoreElements()) {
097: String headerName = (String) enums.nextElement();
098: String headerValue = request.getHeader(headerName);
099: List<String> values = requestHeaders.get(headerName);
100: if (values == null) {
101: values = new ArrayList<String>();
102: requestHeaders.put(headerName, values);
103: }
104: values.add(headerValue);
105: }
106: }
107: return requestHeaders;
108: }
109:
110: private Map<String, List<String>> responseHeaders;
111:
112: /**
113: * sets response headers.
114: */
115: @Override
116: public void setResponseHeaders(Map<String, List<String>> headers) {
117: this .responseHeaders = headers;
118: if (headers == null)
119: return;
120: if (status != 0)
121: response.setStatus(status);
122: response.reset(); // clear all the headers
123:
124: for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
125: String name = entry.getKey();
126: if (name.equalsIgnoreCase("Content-Type")
127: || name.equalsIgnoreCase("Content-Length"))
128: continue; // ignore headers that interfere with the operation
129: for (String value : entry.getValue()) {
130: response.addHeader(name, value);
131: }
132: }
133:
134: }
135:
136: @Override
137: @Property({MessageContext.HTTP_RESPONSE_HEADERS,Packet.OUTBOUND_TRANSPORT_HEADERS})
138: public Map<String, List<String>> getResponseHeaders() {
139: return responseHeaders;
140: }
141:
142: @Override
143: public void setStatus(int status) {
144: this .status = status;
145: // Servlet containers don't seem to like setting of the value multiple times
146: // Moving the following to getOutput()
147: //response.setStatus(status);
148: }
149:
150: @Override
151: @Property(MessageContext.HTTP_RESPONSE_CODE)
152: public int getStatus() {
153: return status;
154: }
155:
156: @Override
157: public void setContentTypeResponseHeader(@NotNull
158: String value) {
159: response.setContentType(value);
160: }
161:
162: @Override
163: public @NotNull
164: InputStream getInput() throws IOException {
165: return request.getInputStream();
166: }
167:
168: @Override
169: public @NotNull
170: OutputStream getOutput() throws IOException {
171: response.setStatus(status);
172: return response.getOutputStream();
173: }
174:
175: public @NotNull
176: WebServiceContextDelegate getWebServiceContextDelegate() {
177: return this ;
178: }
179:
180: public Principal getUserPrincipal(Packet p) {
181: return request.getUserPrincipal();
182: }
183:
184: public boolean isUserInRole(Packet p, String role) {
185: return request.isUserInRole(role);
186: }
187:
188: public @NotNull
189: String getEPRAddress(Packet p, WSEndpoint endpoint) {
190: PortAddressResolver resolver = adapter.owner
191: .createPortAddressResolver(getBaseAddress());
192: String address = resolver.getAddressFor(endpoint
193: .getServiceName(), endpoint.getPortName()
194: .getLocalPart());
195: if (address == null)
196: throw new WebServiceException(WsservletMessages
197: .SERVLET_NO_ADDRESS_AVAILABLE(endpoint
198: .getPortName()));
199: return address;
200: }
201:
202: public String getWSDLAddress(@NotNull
203: Packet request, @NotNull
204: WSEndpoint endpoint) {
205: String eprAddress = getEPRAddress(request, endpoint);
206: if (adapter.getEndpoint().getPort() != null)
207: return eprAddress + "?wsdl";
208: else
209: return null;
210: }
211:
212: @Override
213: @Property(MessageContext.HTTP_REQUEST_METHOD)
214: public @NotNull
215: String getRequestMethod() {
216: return request.getMethod();
217: }
218:
219: @Override
220: public boolean isSecure() {
221: return request.getScheme().equals("https");
222: }
223:
224: @Override
225: public String getRequestHeader(String headerName) {
226: return request.getHeader(headerName);
227: }
228:
229: @Override
230: @Property(MessageContext.QUERY_STRING)
231: public String getQueryString() {
232: return request.getQueryString();
233: }
234:
235: @Override
236: @Property(MessageContext.PATH_INFO)
237: public @NotNull
238: String getPathInfo() {
239: return request.getPathInfo();
240: }
241:
242: public @NotNull
243: String getBaseAddress() {
244: return getBaseAddress(request);
245: }
246:
247: static @NotNull
248: String getBaseAddress(HttpServletRequest request) {
249: StringBuilder buf = new StringBuilder();
250: buf.append(request.getScheme());
251: buf.append("://");
252: buf.append(request.getServerName());
253: buf.append(':');
254: buf.append(request.getServerPort());
255: buf.append(request.getContextPath());
256:
257: return buf.toString();
258: }
259:
260: @Property(MessageContext.SERVLET_CONTEXT)
261: public ServletContext getContext() {
262: return context;
263: }
264:
265: @Property(MessageContext.SERVLET_RESPONSE)
266: public HttpServletResponse getResponse() {
267: return response;
268: }
269:
270: @Property(MessageContext.SERVLET_REQUEST)
271: public HttpServletRequest getRequest() {
272: return request;
273: }
274:
275: @Property(JAXWSProperties.HTTP_REQUEST_URL)
276: public String getRequestURL() {
277: return request.getRequestURL().toString();
278: }
279:
280: @Override
281: public String getProtocol() {
282: return request.getProtocol();
283: }
284:
285: @Override
286: public void setContentLengthResponseHeader(int value) {
287: response.setContentLength(value);
288: }
289:
290: protected PropertyMap getPropertyMap() {
291: return model;
292: }
293:
294: private static final PropertyMap model;
295:
296: static {
297: model = parse(ServletConnectionImpl.class);
298: }
299: }
|