001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.server.webservices;
017:
018: import org.apache.openejb.server.httpd.HttpListener;
019: import org.apache.openejb.server.httpd.HttpRequest;
020: import org.apache.openejb.server.httpd.HttpResponse;
021: import org.apache.openejb.server.httpd.ServletRequestAdapter;
022: import org.apache.openejb.server.httpd.ServletResponseAdapter;
023:
024: import javax.servlet.Servlet;
025: import javax.servlet.ServletConfig;
026: import javax.servlet.ServletContext;
027: import javax.servlet.ServletException;
028: import javax.servlet.ServletRequest;
029: import javax.servlet.ServletResponse;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032: import javax.servlet.http.HttpSession;
033: import javax.xml.rpc.ServiceException;
034: import javax.xml.rpc.handler.MessageContext;
035: import javax.xml.rpc.server.ServiceLifecycle;
036: import javax.xml.rpc.server.ServletEndpointContext;
037: import java.io.IOException;
038: import java.security.Principal;
039:
040: public class WsServlet implements Servlet {
041: public static final String POJO_CLASS = WsServlet.class.getName()
042: + "@pojoClassName";
043: public static final String WEBSERVICE_CONTAINER = WsServlet.class
044: .getName()
045: + "@WebServiceContainer";
046:
047: private static final DefaultContext DEFAULT_CONTEXT = new DefaultContext();
048: private static final ThreadLocal<ServletEndpointContext> endpointContext = new ThreadLocal<ServletEndpointContext>();
049:
050: private ServletConfig config;
051: private Object pojo;
052: private HttpListener service;
053:
054: public WsServlet() {
055: }
056:
057: public WsServlet(HttpListener service) {
058: this .service = service;
059: }
060:
061: public void init(ServletConfig config) throws ServletException {
062: this .config = config;
063:
064: // this is only used by JaxRPC pojo services
065: pojo = createPojoInstance();
066: if (pojo instanceof ServiceLifecycle) {
067: try {
068: ((ServiceLifecycle) pojo).init(new InstanceContext(
069: config.getServletContext()));
070: } catch (ServiceException e) {
071: throw new ServletException(
072: "Unable to initialize ServiceEndpoint", e);
073: }
074: }
075: getService();
076: }
077:
078: public ServletConfig getServletConfig() {
079: return config;
080: }
081:
082: public String getServletInfo() {
083: return "Webservice Servlet " + getService();
084: }
085:
086: public void service(ServletRequest req, ServletResponse res)
087: throws ServletException, IOException {
088: HttpListener service = getService();
089: if (service == null)
090: throw new ServletException(
091: "WebServiceContainer has not been set");
092:
093: ServletEndpointContext context = getContext();
094: endpointContext.set(new InvocationContext(
095: (HttpServletRequest) req));
096: try {
097: res.setContentType("text/xml");
098: HttpRequest httpRequest = new ServletRequestAdapter(
099: (HttpServletRequest) req,
100: (HttpServletResponse) res, config
101: .getServletContext());
102: HttpResponse httpResponse = new ServletResponseAdapter(
103: (HttpServletResponse) res);
104:
105: if (pojo != null) {
106: req.setAttribute(WsConstants.POJO_INSTANCE, pojo);
107: }
108:
109: try {
110: service.onMessage(httpRequest, httpResponse);
111: } catch (IOException e) {
112: throw e;
113: } catch (ServletException e) {
114: throw e;
115: } catch (Exception e) {
116: throw new ServletException(
117: "Error processing webservice request", e);
118: }
119: } finally {
120: endpointContext.set(context);
121: }
122: }
123:
124: public void destroy() {
125: if (pojo instanceof ServiceLifecycle) {
126: ((ServiceLifecycle) pojo).destroy();
127: }
128: }
129:
130: private Object createPojoInstance() throws ServletException {
131: ServletContext context = getServletConfig().getServletContext();
132:
133: String pojoClassId = context.getInitParameter(POJO_CLASS);
134: if (pojoClassId == null)
135: return null;
136:
137: Class pojoClass = (Class) context.getAttribute(pojoClassId);
138: if (pojoClass == null)
139: return null;
140:
141: try {
142: Object instance = pojoClass.newInstance();
143: return instance;
144: } catch (Exception e) {
145: throw new ServletException(
146: "Unable to instantiate POJO WebService class: "
147: + pojoClass.getName(), e);
148: }
149: }
150:
151: private synchronized HttpListener getService() {
152: if (service == null) {
153: ServletConfig config = getServletConfig();
154: String webServiceContainerId = config
155: .getInitParameter(WEBSERVICE_CONTAINER);
156: if (webServiceContainerId != null) {
157: service = (HttpListener) config.getServletContext()
158: .getAttribute(webServiceContainerId);
159: }
160: }
161: return service;
162: }
163:
164: private static ServletEndpointContext getContext() {
165: ServletEndpointContext context = endpointContext.get();
166: return context != null ? context : DEFAULT_CONTEXT;
167: }
168:
169: private static class InstanceContext implements
170: ServletEndpointContext {
171: private final ServletContext servletContext;
172:
173: public InstanceContext(ServletContext servletContext) {
174: this .servletContext = servletContext;
175: }
176:
177: public MessageContext getMessageContext() {
178: return getContext().getMessageContext();
179: }
180:
181: public Principal getUserPrincipal() {
182: return getContext().getUserPrincipal();
183: }
184:
185: public HttpSession getHttpSession() {
186: return getContext().getHttpSession();
187: }
188:
189: public ServletContext getServletContext() {
190: return servletContext;
191: }
192:
193: public boolean isUserInRole(String s) {
194: return getContext().isUserInRole(s);
195: }
196: }
197:
198: private static class InvocationContext implements
199: ServletEndpointContext {
200:
201: private final HttpServletRequest request;
202:
203: public InvocationContext(HttpServletRequest request) {
204: this .request = request;
205: }
206:
207: public MessageContext getMessageContext() {
208: return (MessageContext) request
209: .getAttribute(WsConstants.MESSAGE_CONTEXT);
210: }
211:
212: public Principal getUserPrincipal() {
213: return request.getUserPrincipal();
214: }
215:
216: public HttpSession getHttpSession() {
217: return request.getSession();
218: }
219:
220: public ServletContext getServletContext() {
221: throw new IllegalAccessError(
222: "InstanceContext should never delegate this method.");
223: }
224:
225: public boolean isUserInRole(String s) {
226: return request.isUserInRole(s);
227: }
228: }
229:
230: private static class DefaultContext implements
231: ServletEndpointContext {
232:
233: public MessageContext getMessageContext() {
234: throw new IllegalStateException(
235: "Method cannot be called outside a request context");
236: }
237:
238: public Principal getUserPrincipal() {
239: throw new IllegalStateException(
240: "Method cannot be called outside a request context");
241: }
242:
243: public HttpSession getHttpSession() {
244: throw new javax.xml.rpc.JAXRPCException(
245: "Method cannot be called outside an http request context");
246: }
247:
248: public ServletContext getServletContext() {
249: throw new IllegalAccessError(
250: "InstanceContext should never delegate this method.");
251: }
252:
253: public boolean isUserInRole(String s) {
254: throw new IllegalStateException(
255: "Method cannot be called outside a request context");
256: }
257: }
258: }
|