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.auth.Subject;
25 import javax.servlet.ServletException;
26 import javax.servlet.ServletRequest;
27 import javax.servlet.ServletResponse;
28 import javax.servlet.UnavailableException;
29
30 import org.apache.geronimo.gbean.GBeanInfo;
31 import org.apache.geronimo.gbean.GBeanInfoBuilder;
32 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
33 import org.apache.geronimo.management.Servlet;
34 import org.apache.geronimo.security.Callers;
35 import org.apache.geronimo.security.ContextManager;
36 import org.mortbay.jetty.servlet.ServletHolder;
37
38
39 /**
40 * This ServletHolder's sole purpose is to provide the thread's current
41 * ServletHolder for realms that are interested in the current servlet, e.g.
42 * current servlet name.
43 * <p/>
44 * It is also being our servlet gbean for now. We could gbean-ize the superclass to avoid the thread local access.
45 *
46 * @version $Rev: 470597 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
47 * @see JAASJettyRealm#isUserInRole(java.security.Principal, String)
48 */
49 public class JettyServletHolder extends ServletHolder implements Servlet {
50 private static final ThreadLocal currentServletName = new ThreadLocal();
51 private final Subject runAsSubject;
52 private final String objectName;
53
54
55 public JettyServletHolder() {
56 this.objectName = null;
57 this.runAsSubject = null;
58 }
59
60 public JettyServletHolder(String objectName,
61 String servletName,
62 String servletClassName,
63 String jspFile,
64 Map initParams,
65 Integer loadOnStartup,
66 Set servletMappings,
67 Subject runAsSubject,
68 ServletHolder previous,
69 JettyServletRegistration context) throws Exception {
70 super(context == null ? null : context.getServletHandler(), servletName, servletClassName, jspFile);
71
72
73 if (context != null) {
74 putAll(initParams);
75 if (loadOnStartup != null) {
76
77 setInitOrder(loadOnStartup.intValue());
78 }
79
80 context.registerServletHolder(this, servletName, servletMappings, objectName);
81 }
82 this.runAsSubject = runAsSubject;
83 this.objectName = objectName;
84 }
85
86
87
88
89 public String getServletName() {
90 return getName();
91 }
92
93
94
95 /**
96 * Service a request with this servlet. Set the ThreadLocal to hold the
97 * current JettyServletHolder.
98 */
99 public void handle(ServletRequest request, ServletResponse response)
100 throws ServletException, UnavailableException, IOException {
101
102 setCurrentServletName(getServletName());
103 if (runAsSubject == null) {
104 super.handle(request, response);
105 } else {
106 Callers oldCallers = ContextManager.pushNextCaller(runAsSubject);
107 try {
108 super.handle(request, response);
109 } finally {
110 ContextManager.popCallers(oldCallers);
111 }
112 }
113 }
114
115 /**
116 * Provide the thread's current JettyServletHolder
117 *
118 * @return the thread's current JettyServletHolder
119 * @see org.apache.geronimo.jetty.JAASJettyRealm#isUserInRole(java.security.Principal, java.lang.String)
120 */
121 static String getCurrentServletName() {
122 return (String) currentServletName.get();
123 }
124
125 static void setCurrentServletName(String servletName) {
126 currentServletName.set(servletName);
127 }
128
129 public String getObjectName() {
130 return objectName;
131 }
132
133 public boolean isStateManageable() {
134 return false;
135 }
136
137 public boolean isStatisticsProvider() {
138 return false;
139 }
140
141 public boolean isEventProvider() {
142 return false;
143 }
144
145 public static final GBeanInfo GBEAN_INFO;
146
147 static {
148 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyServletHolder.class, NameFactory.SERVLET);
149
150 infoBuilder.addInterface(ServletHolder.class);
151
152 infoBuilder.addAttribute("servletName", String.class, true);
153 infoBuilder.addAttribute("servletClass", String.class, true);
154 infoBuilder.addAttribute("jspFile", String.class, true);
155 infoBuilder.addAttribute("initParams", Map.class, true);
156 infoBuilder.addAttribute("loadOnStartup", Integer.class, true);
157 infoBuilder.addAttribute("servletMappings", Set.class, true);
158 infoBuilder.addAttribute("runAsSubject", Subject.class, true);
159 infoBuilder.addAttribute("objectName", String.class, false);
160 infoBuilder.addInterface(Servlet.class);
161
162 infoBuilder.addReference("Previous", ServletHolder.class, NameFactory.SERVLET);
163 infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class, NameFactory.WEB_MODULE);
164
165 infoBuilder.setConstructor(new String[]{"objectName",
166 "servletName",
167 "servletClass",
168 "jspFile",
169 "initParams",
170 "loadOnStartup",
171 "servletMappings",
172 "runAsSubject",
173 "Previous",
174 "JettyServletRegistration"});
175
176 GBEAN_INFO = infoBuilder.getBeanInfo();
177 }
178
179 public static GBeanInfo getGBeanInfo() {
180 return GBEAN_INFO;
181 }
182 }