View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  package org.apache.geronimo.jetty;
19  
20  import java.io.IOException;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import javax.security.jacc.PolicyContext;
25  import javax.servlet.ServletContext;
26  import javax.servlet.ServletException;
27  import javax.servlet.ServletRequest;
28  import javax.servlet.ServletResponse;
29  import javax.servlet.UnavailableException;
30  
31  import org.apache.geronimo.gbean.GBeanInfo;
32  import org.apache.geronimo.gbean.GBeanInfoBuilder;
33  import org.apache.geronimo.gbean.GBeanLifecycle;
34  import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
35  import org.apache.geronimo.webservices.POJOWebServiceServlet;
36  import org.apache.geronimo.webservices.WebServiceContainer;
37  import org.apache.geronimo.webservices.WebServiceContainerInvoker;
38  import org.apache.geronimo.webservices.WebServiceContainerFactory;
39  import org.mortbay.jetty.servlet.ServletHolder;
40  import org.mortbay.jetty.servlet.ServletHttpRequest;
41  
42  
43  /**
44   * This is intended to hold the web service stack for an axis POJO web service.
45   * It is starting life as a copy of JettyServletHolder.
46   *
47   * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
48   */
49  public class JettyPOJOWebServiceHolder extends ServletHolder implements GBeanLifecycle {
50      private WebServiceContainer webServiceContainer;
51      private Set servletMappings;
52      private JettyServletRegistration context;
53      private String pojoClassName;
54  
55      //todo consider interface instead of this constructor for endpoint use.
56      public JettyPOJOWebServiceHolder() {
57  
58      }
59  
60      public JettyPOJOWebServiceHolder(String pojoClassName,
61                                       String servletName,
62                                       Map initParams,
63                                       Integer loadOnStartup,
64                                       Set servletMappings,
65                                       WebServiceContainerFactory webServiceContainerFactory,
66                                       ServletHolder previous,    //dependency for startup ordering
67                                       JettyServletRegistration context) throws Exception {
68          super(context == null ? null : context.getServletHandler(), servletName, POJOWebServiceServlet.class.getName(), null);
69          //context will be null only for use as "default servlet info holder" in deployer.
70  
71          this.pojoClassName = pojoClassName;
72          this.context = context;
73          this.webServiceContainer = webServiceContainerFactory == null? null: webServiceContainerFactory.getWebServiceContainer();
74          if (context != null) {
75              putAll(initParams);
76              if (loadOnStartup != null) {
77                  setInitOrder(loadOnStartup.intValue());
78              }
79              this.servletMappings = servletMappings;
80          }
81      }
82  
83      //todo how do we stop/destroy the servlet?
84      //todo is start called twice???
85  
86      public String getServletName() {
87          return getName();
88      }
89  
90      /**
91       * Service a request with this servlet.  Set the ThreadLocal to hold the
92       * current JettyServletHolder.
93       */
94      public void handle(ServletRequest request, ServletResponse response)
95              throws ServletException, UnavailableException, IOException {
96  
97          //  TODO There has to be some way to get this in on the Servlet's init method.
98  //        request.setAttribute(POJOWebServiceServlet.WEBSERVICE_CONTAINER, webServiceContainer);
99  
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 }