001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.jetty;
019    
020    import java.io.IOException;
021    import java.util.Map;
022    import java.util.Set;
023    
024    import javax.security.jacc.PolicyContext;
025    import javax.servlet.ServletContext;
026    import javax.servlet.ServletException;
027    import javax.servlet.ServletRequest;
028    import javax.servlet.ServletResponse;
029    import javax.servlet.UnavailableException;
030    
031    import org.apache.geronimo.gbean.GBeanInfo;
032    import org.apache.geronimo.gbean.GBeanInfoBuilder;
033    import org.apache.geronimo.gbean.GBeanLifecycle;
034    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
035    import org.apache.geronimo.webservices.POJOWebServiceServlet;
036    import org.apache.geronimo.webservices.WebServiceContainer;
037    import org.apache.geronimo.webservices.WebServiceContainerInvoker;
038    import org.apache.geronimo.webservices.WebServiceContainerFactory;
039    import org.mortbay.jetty.servlet.ServletHolder;
040    import org.mortbay.jetty.servlet.ServletHttpRequest;
041    
042    
043    /**
044     * This is intended to hold the web service stack for an axis POJO web service.
045     * It is starting life as a copy of JettyServletHolder.
046     *
047     * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
048     */
049    public class JettyPOJOWebServiceHolder extends ServletHolder implements GBeanLifecycle {
050        private WebServiceContainer webServiceContainer;
051        private Set servletMappings;
052        private JettyServletRegistration context;
053        private String pojoClassName;
054    
055        //todo consider interface instead of this constructor for endpoint use.
056        public JettyPOJOWebServiceHolder() {
057    
058        }
059    
060        public JettyPOJOWebServiceHolder(String pojoClassName,
061                                         String servletName,
062                                         Map initParams,
063                                         Integer loadOnStartup,
064                                         Set servletMappings,
065                                         WebServiceContainerFactory webServiceContainerFactory,
066                                         ServletHolder previous,    //dependency for startup ordering
067                                         JettyServletRegistration context) throws Exception {
068            super(context == null ? null : context.getServletHandler(), servletName, POJOWebServiceServlet.class.getName(), null);
069            //context will be null only for use as "default servlet info holder" in deployer.
070    
071            this.pojoClassName = pojoClassName;
072            this.context = context;
073            this.webServiceContainer = webServiceContainerFactory == null? null: webServiceContainerFactory.getWebServiceContainer();
074            if (context != null) {
075                putAll(initParams);
076                if (loadOnStartup != null) {
077                    setInitOrder(loadOnStartup.intValue());
078                }
079                this.servletMappings = servletMappings;
080            }
081        }
082    
083        //todo how do we stop/destroy the servlet?
084        //todo is start called twice???
085    
086        public String getServletName() {
087            return getName();
088        }
089    
090        /**
091         * Service a request with this servlet.  Set the ThreadLocal to hold the
092         * current JettyServletHolder.
093         */
094        public void handle(ServletRequest request, ServletResponse response)
095                throws ServletException, UnavailableException, IOException {
096    
097            //  TODO There has to be some way to get this in on the Servlet's init method.
098    //        request.setAttribute(POJOWebServiceServlet.WEBSERVICE_CONTAINER, webServiceContainer);
099    
100            JettyServletHolder.setCurrentServletName(getServletName());
101            PolicyContext.setHandlerData(ServletHttpRequest.unwrap(request));
102    
103            super.handle(request, response);
104        }
105    
106        public void doStart() throws Exception {
107            if (context != null) {
108                Class pojoClass = context.getWebClassLoader().loadClass(pojoClassName);
109    
110                /* DMB: Hack! I really just want to override initServlet and give a reference of the WebServiceContainer to the servlet before we call init on it.
111                 * But this will have to do instead....
112                 */
113                ServletContext servletContext = this.context.getServletHandler().getServletContext();
114    
115                // Make up an ID for the WebServiceContainer
116                // put a reference the ID in the init-params
117                // put the WebServiceContainer in the webapp context keyed by its ID
118                String webServicecontainerID = getServletName() + WebServiceContainerInvoker.WEBSERVICE_CONTAINER + webServiceContainer.hashCode();
119                put(WebServiceContainerInvoker.WEBSERVICE_CONTAINER, webServicecontainerID);
120                servletContext.setAttribute(webServicecontainerID, webServiceContainer);
121    
122                // Same for the POJO Class
123                String pojoClassID = getServletName() + POJOWebServiceServlet.POJO_CLASS + pojoClass.hashCode();
124                put(POJOWebServiceServlet.POJO_CLASS, pojoClassID);
125                servletContext.setAttribute(pojoClassID, pojoClass);
126    
127                //this now starts the servlet in the appropriate context
128                //TODO check that we should not call this a servlet for jsr-77 benefit.
129                context.registerServletHolder(this, getServletName(), this.servletMappings, null);
130    //            start();
131            }
132        }
133    
134        public void doStop() throws Exception {
135        }
136    
137        public void doFail() {
138        }
139    
140        public static final GBeanInfo GBEAN_INFO;
141    
142        static {
143            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyPOJOWebServiceHolder.class, NameFactory.SERVLET_WEB_SERVICE_TEMPLATE);
144            //todo replace with interface
145            infoBuilder.addInterface(ServletHolder.class);
146    
147            infoBuilder.addAttribute("pojoClassName", String.class, true);
148            infoBuilder.addAttribute("servletName", String.class, true);
149            infoBuilder.addAttribute("initParams", Map.class, true);
150            infoBuilder.addAttribute("loadOnStartup", Integer.class, true);
151            infoBuilder.addAttribute("servletMappings", Set.class, true);
152            infoBuilder.addReference("WebServiceContainerFactory", WebServiceContainerFactory.class);
153            infoBuilder.addReference("Previous", ServletHolder.class, NameFactory.SERVLET);
154            infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class);
155    
156            infoBuilder.setConstructor(new String[]{"pojoClassName",
157                                                    "servletName",
158                                                    "initParams",
159                                                    "loadOnStartup",
160                                                    "servletMappings",
161                                                    "WebServiceContainerFactory",
162                                                    "Previous",
163                                                    "JettyServletRegistration"});
164    
165            GBEAN_INFO = infoBuilder.getBeanInfo();
166        }
167    
168        public static GBeanInfo getGBeanInfo() {
169            return GBEAN_INFO;
170        }
171    
172    
173    }