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     */
017    package org.apache.geronimo.webservices;
018    
019    import java.io.IOException;
020    import java.security.Principal;
021    import javax.servlet.Servlet;
022    import javax.servlet.ServletConfig;
023    import javax.servlet.ServletException;
024    import javax.servlet.ServletRequest;
025    import javax.servlet.ServletResponse;
026    import javax.servlet.ServletContext;
027    import javax.servlet.http.HttpServletRequest;
028    import javax.servlet.http.HttpSession;
029    import javax.xml.rpc.server.ServiceLifecycle;
030    import javax.xml.rpc.server.ServletEndpointContext;
031    import javax.xml.rpc.ServiceException;
032    import javax.xml.rpc.handler.MessageContext;
033    
034    /**
035     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
036     */
037    public class ServiceLifecycleManager implements Servlet {
038    
039        private final ServiceLifecycle managedService;
040        private final Servlet next;
041    
042        public ServiceLifecycleManager(Servlet next, ServiceLifecycle managedService) {
043            this.next = next;
044            this.managedService = managedService;
045        }
046    
047        public void init(ServletConfig config) throws ServletException {
048            next.init(config);
049            try {
050                managedService.init(new InstanceContext(config.getServletContext()));
051            } catch (ServiceException e) {
052                throw new ServletException("Unable to initialize ServiceEndpoint", e);
053            }
054        }
055    
056        public ServletConfig getServletConfig() {
057            return next.getServletConfig();
058        }
059    
060        public String getServletInfo() {
061            return next.getServletInfo();
062        }
063    
064        public void destroy() {
065            managedService.destroy();
066            next.destroy();
067        }
068    
069        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
070            ServletEndpointContext context = getContext();
071            try {
072                endpointContext.set(new InvocationContext((HttpServletRequest) req));
073                next.service(req, res);
074            } finally {
075                endpointContext.set(context);
076            }
077        }
078    
079        private static final DefaultContext DEFAULT_CONTEXT = new DefaultContext();
080    
081        private static final ThreadLocal endpointContext = new ThreadLocal();
082    
083    
084        private static ServletEndpointContext getContext() {
085            ServletEndpointContext context = (ServletEndpointContext) endpointContext.get();
086            return context != null ? context : DEFAULT_CONTEXT;
087        }
088    
089        static class InstanceContext implements ServletEndpointContext {
090            private final ServletContext servletContext;
091    
092            public InstanceContext(ServletContext servletContext) {
093                this.servletContext = servletContext;
094            }
095    
096            public MessageContext getMessageContext() {
097                return getContext().getMessageContext();
098            }
099    
100            public Principal getUserPrincipal() {
101                return getContext().getUserPrincipal();
102            }
103    
104            public HttpSession getHttpSession() {
105                return getContext().getHttpSession();
106            }
107    
108            public ServletContext getServletContext() {
109                return servletContext;
110            }
111    
112            public boolean isUserInRole(String s) {
113                return getContext().isUserInRole(s);
114            }
115        }
116    
117        static class InvocationContext implements ServletEndpointContext {
118    
119            private final HttpServletRequest request;
120    
121            public InvocationContext(HttpServletRequest request) {
122                this.request = request;
123            }
124    
125            public MessageContext getMessageContext() {
126                return (MessageContext) request.getAttribute(WebServiceContainer.MESSAGE_CONTEXT);
127            }
128    
129            public Principal getUserPrincipal() {
130                return request.getUserPrincipal();
131            }
132    
133            public HttpSession getHttpSession() {
134                return request.getSession();
135            }
136    
137            public ServletContext getServletContext() {
138                throw new IllegalAccessError("InstanceContext should never delegate this method.");
139            }
140    
141            public boolean isUserInRole(String s) {
142                return request.isUserInRole(s);
143            }
144        }
145    
146        static class DefaultContext implements ServletEndpointContext {
147    
148            public MessageContext getMessageContext() {
149                throw new IllegalStateException("Method cannot be called outside a request context");
150            }
151    
152            public Principal getUserPrincipal() {
153                throw new IllegalStateException("Method cannot be called outside a request context");
154            }
155    
156            public HttpSession getHttpSession() {
157                throw new javax.xml.rpc.JAXRPCException("Method cannot be called outside an http request context");
158            }
159    
160            public ServletContext getServletContext() {
161                throw new IllegalAccessError("InstanceContext should never delegate this method.");
162            }
163    
164            public boolean isUserInRole(String s) {
165                throw new IllegalStateException("Method cannot be called outside a request context");
166            }
167        }
168    }