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.jetty6; 018 019 import java.io.IOException; 020 import java.util.Map; 021 import java.util.Set; 022 023 import javax.security.auth.Subject; 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 import javax.servlet.http.HttpServletRequest; 031 032 import org.apache.geronimo.gbean.GBeanInfo; 033 import org.apache.geronimo.gbean.GBeanInfoBuilder; 034 import org.apache.geronimo.gbean.GBeanLifecycle; 035 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 036 import org.apache.geronimo.webservices.POJOWebServiceServlet; 037 import org.apache.geronimo.webservices.WebServiceContainer; 038 import org.apache.geronimo.webservices.WebServiceContainerInvoker; 039 import org.apache.geronimo.webservices.WebServiceContainerFactory; 040 import org.mortbay.jetty.Request; 041 import org.mortbay.jetty.servlet.ServletHolder; 042 043 044 /** 045 * This is intended to hold the web service stack for an axis POJO web service. 046 * It is starting life as a copy of JettyServletHolder. 047 * 048 * @version $Rev: 549859 $ $Date: 2007-06-22 12:05:13 -0400 (Fri, 22 Jun 2007) $ 049 */ 050 public class JettyPOJOWebServiceHolder implements GBeanLifecycle { 051 private final ServletHolder servletHolder; 052 private final WebServiceContainer webServiceContainer; 053 private final Set servletMappings; 054 private final JettyServletRegistration context; 055 private final String pojoClassName; 056 057 //todo consider interface instead of this constructor for endpoint use. 058 public JettyPOJOWebServiceHolder() { 059 servletHolder = null; 060 webServiceContainer = null; 061 servletMappings = null; 062 context = null; 063 pojoClassName = null; 064 } 065 066 public JettyPOJOWebServiceHolder(String pojoClassName, 067 String servletName, 068 Map initParams, 069 Integer loadOnStartup, 070 Set servletMappings, 071 String runAsRole, 072 WebServiceContainerFactory webServiceContainerFactory, 073 JettyServletRegistration context) throws Exception { 074 Subject runAsSubject = context == null? null: context.getSubjectForRole(runAsRole); 075 servletHolder = new InternalJettyServletHolder(context == null? null: context.getLifecycleChain(), runAsSubject, context); 076 //context will be null only for use as "default servlet info holder" in deployer. 077 078 this.pojoClassName = pojoClassName; 079 this.context = context; 080 this.webServiceContainer = webServiceContainerFactory == null? null: webServiceContainerFactory.getWebServiceContainer(); 081 this.servletMappings = servletMappings; 082 if (context != null) { 083 servletHolder.setName(servletName); 084 servletHolder.setClassName(POJOWebServiceServlet.class.getName()); 085 servletHolder.setInitParameters(initParams); 086 if (loadOnStartup != null) { 087 servletHolder.setInitOrder(loadOnStartup.intValue()); 088 } 089 } 090 } 091 092 //todo how do we stop/destroy the servlet? 093 //todo is start called twice??? 094 095 public String getServletName() { 096 return servletHolder.getName(); 097 } 098 099 /** 100 * TODO THIS IS NOT CALLED!!! only the ServletHolder is!! 101 * Service a request with this servlet. Set the ThreadLocal to hold the 102 * current JettyServletHolder. 103 */ 104 public void handle(ServletRequest request, ServletResponse response) 105 throws ServletException, UnavailableException, IOException { 106 107 // TODO There has to be some way to get this in on the Servlet's init method. 108 // request.setAttribute(POJOWebServiceServlet.WEBSERVICE_CONTAINER, webServiceContainer); 109 110 InternalJettyServletHolder.setCurrentServletName(getServletName()); 111 PolicyContext.setHandlerData(Request.getRequest((HttpServletRequest) request)); 112 113 servletHolder.handle(request, response); 114 } 115 116 public void doStart() throws Exception { 117 if (context != null) { 118 Class pojoClass = context.getWebClassLoader().loadClass(pojoClassName); 119 120 /* 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. 121 * But this will have to do instead.... 122 */ 123 ServletContext servletContext = this.context.getServletHandler().getServletContext(); 124 125 // Make up an ID for the WebServiceContainer 126 // put a reference the ID in the init-params 127 // put the WebServiceContainer in the webapp context keyed by its ID 128 String webServicecontainerID = getServletName() + WebServiceContainerInvoker.WEBSERVICE_CONTAINER + webServiceContainer.hashCode(); 129 servletHolder.setInitParameter(WebServiceContainerInvoker.WEBSERVICE_CONTAINER, webServicecontainerID); 130 servletContext.setAttribute(webServicecontainerID, webServiceContainer); 131 132 // Same for the POJO Class 133 String pojoClassID = getServletName() + POJOWebServiceServlet.POJO_CLASS + pojoClass.hashCode(); 134 servletHolder.setInitParameter(POJOWebServiceServlet.POJO_CLASS, pojoClassID); 135 servletContext.setAttribute(pojoClassID, pojoClass); 136 137 //this now starts the servlet in the appropriate context 138 //TODO check that we should not call this a servlet for jsr-77 benefit. 139 context.registerServletHolder(servletHolder, getServletName(), this.servletMappings, null); 140 servletHolder.start(); 141 } 142 } 143 144 public void doStop() throws Exception { 145 servletHolder.stop(); 146 } 147 148 public void doFail() { 149 try { 150 servletHolder.stop(); 151 } catch (Exception e) { 152 //ignore ?? 153 } 154 } 155 156 public static final GBeanInfo GBEAN_INFO; 157 158 static { 159 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyPOJOWebServiceHolder.class, NameFactory.SERVLET_WEB_SERVICE_TEMPLATE); 160 //todo replace with interface 161 // infoBuilder.addInterface(ServletHolder.class); 162 163 infoBuilder.addAttribute("pojoClassName", String.class, true); 164 infoBuilder.addAttribute("servletName", String.class, true); 165 infoBuilder.addAttribute("initParams", Map.class, true); 166 infoBuilder.addAttribute("loadOnStartup", Integer.class, true); 167 infoBuilder.addAttribute("servletMappings", Set.class, true); 168 infoBuilder.addAttribute("runAsRole", String.class, true); 169 infoBuilder.addReference("WebServiceContainerFactory", WebServiceContainerFactory.class); 170 infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class); 171 172 infoBuilder.setConstructor(new String[]{"pojoClassName", 173 "servletName", 174 "initParams", 175 "loadOnStartup", 176 "servletMappings", 177 "runAsRole", 178 "WebServiceContainerFactory", 179 "JettyServletRegistration"}); 180 181 GBEAN_INFO = infoBuilder.getBeanInfo(); 182 } 183 184 public static GBeanInfo getGBeanInfo() { 185 return GBEAN_INFO; 186 } 187 188 189 }