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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
049 */
050 public class JettyPOJOWebServiceHolder implements ServletNameSource, 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 }