1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.jetty.servlet;
17
18 import java.io.IOException;
19 import java.util.Enumeration;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import javax.servlet.ServletContext;
24 import javax.servlet.ServletException;
25 import javax.servlet.UnavailableException;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletRequestWrapper;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.mortbay.jetty.Handler;
32 import org.mortbay.jetty.handler.ContextHandler;
33 import org.mortbay.jetty.handler.HandlerWrapper;
34 import org.mortbay.log.Log;
35 import org.mortbay.util.LazyList;
36 import org.mortbay.util.URIUtil;
37 ;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class Invoker extends HttpServlet
62 {
63
64 private ContextHandler _contextHandler;
65 private ServletHandler _servletHandler;
66 private Map.Entry _invokerEntry;
67 private Map _parameters;
68 private boolean _nonContextServlets;
69 private boolean _verbose;
70
71
72 public void init()
73 {
74 ServletContext config=getServletContext();
75 _contextHandler=((ContextHandler.SContext)config).getContextHandler();
76
77 Handler handler=_contextHandler.getHandler();
78 while (handler!=null && !(handler instanceof ServletHandler) && (handler instanceof HandlerWrapper))
79 handler=((HandlerWrapper)handler).getHandler();
80 _servletHandler = (ServletHandler)handler;
81 Enumeration e = getInitParameterNames();
82 while(e.hasMoreElements())
83 {
84 String param=(String)e.nextElement();
85 String value=getInitParameter(param);
86 String lvalue=value.toLowerCase();
87 if ("nonContextServlets".equals(param))
88 {
89 _nonContextServlets=value.length()>0 && lvalue.startsWith("t");
90 }
91 if ("verbose".equals(param))
92 {
93 _verbose=value.length()>0 && lvalue.startsWith("t");
94 }
95 else
96 {
97 if (_parameters==null)
98 _parameters=new HashMap();
99 _parameters.put(param,value);
100 }
101 }
102 }
103
104
105 protected void service(HttpServletRequest request, HttpServletResponse response)
106 throws ServletException, IOException
107 {
108
109 boolean included=false;
110 String servlet_path=(String)request.getAttribute(Dispatcher.__INCLUDE_SERVLET_PATH);
111 if (servlet_path==null)
112 servlet_path=request.getServletPath();
113 else
114 included=true;
115 String path_info = (String)request.getAttribute(Dispatcher.__INCLUDE_PATH_INFO);
116 if (path_info==null)
117 path_info=request.getPathInfo();
118
119
120 String servlet = path_info;
121 if (servlet==null || servlet.length()<=1 )
122 {
123 response.sendError(404);
124 return;
125 }
126
127
128 int i0=servlet.charAt(0)=='/'?1:0;
129 int i1=servlet.indexOf('/',i0);
130 servlet=i1<0?servlet.substring(i0):servlet.substring(i0,i1);
131
132
133 ServletHolder[] holders = _servletHandler.getServlets();
134 ServletHolder holder = getHolder (holders, servlet);
135
136 if (holder!=null)
137 {
138
139
140 Log.debug("Adding servlet mapping for named servlet:"+servlet+":"+URIUtil.addPaths(servlet_path,servlet)+"/*");
141 ServletMapping mapping = new ServletMapping();
142 mapping.setServletName(servlet);
143 mapping.setPathSpec(URIUtil.addPaths(servlet_path,servlet)+"/*");
144 _servletHandler.setServletMappings((ServletMapping[])LazyList.addToArray(_servletHandler.getServletMappings(), mapping, ServletMapping.class));
145 }
146 else
147 {
148
149 if (servlet.endsWith(".class"))
150 servlet=servlet.substring(0,servlet.length()-6);
151 if (servlet==null || servlet.length()==0)
152 {
153 response.sendError(404);
154 return;
155 }
156
157 synchronized(_servletHandler)
158 {
159
160 _invokerEntry=_servletHandler.getHolderEntry(servlet_path);
161
162
163 String path=URIUtil.addPaths(servlet_path,servlet);
164 Map.Entry entry = _servletHandler.getHolderEntry(path);
165
166 if (entry!=null && !entry.equals(_invokerEntry))
167 {
168
169 holder=(ServletHolder)entry.getValue();
170 }
171 else
172 {
173
174 Log.debug("Making new servlet="+servlet+" with path="+path+"/*");
175 holder=_servletHandler.addServlet(servlet, path+"/*");
176 Map.Entry eee = _servletHandler.getHolderEntry(path);
177 ServletMapping mapping = new ServletMapping();
178 mapping.setServletName(servlet);
179 mapping.setPathSpec(path+".class/*");
180 _servletHandler.setServletMappings((ServletMapping[])LazyList.addToArray(_servletHandler.getServletMappings(), mapping, ServletMapping.class));
181
182
183
184
185 if (_parameters!=null)
186 holder.setInitParameters(_parameters);
187
188 try {holder.start();}
189 catch (Exception e)
190 {
191 Log.debug(e);
192 throw new UnavailableException(e.toString());
193 }
194
195
196 if (!_nonContextServlets)
197 {
198 Object s=holder.getServlet();
199
200 if (_contextHandler.getClassLoader()!=
201 s.getClass().getClassLoader())
202 {
203 try
204 {
205 holder.stop();
206 }
207 catch (Exception e)
208 {
209 Log.ignore(e);
210 }
211
212 Log.warn("Dynamic servlet "+s+
213 " not loaded from context "+
214 request.getContextPath());
215 throw new UnavailableException("Not in context");
216 }
217 }
218
219 if (_verbose)
220 Log.debug("Dynamic load '"+servlet+"' at "+path);
221 }
222 }
223 }
224
225 if (holder!=null)
226 holder.handle(new Request(request,included,servlet,servlet_path,path_info),
227 response);
228 else
229 {
230 Log.info("Can't find holder for servlet: "+servlet);
231 response.sendError(404);
232 }
233
234
235 }
236
237
238 class Request extends HttpServletRequestWrapper
239 {
240 String _servletPath;
241 String _pathInfo;
242 boolean _included;
243
244
245 Request(HttpServletRequest request,
246 boolean included,
247 String name,
248 String servletPath,
249 String pathInfo)
250 {
251 super(request);
252 _included=included;
253 _servletPath=URIUtil.addPaths(servletPath,name);
254 _pathInfo=pathInfo.substring(name.length()+1);
255 if (_pathInfo.length()==0)
256 _pathInfo=null;
257 }
258
259
260 public String getServletPath()
261 {
262 if (_included)
263 return super.getServletPath();
264 return _servletPath;
265 }
266
267
268 public String getPathInfo()
269 {
270 if (_included)
271 return super.getPathInfo();
272 return _pathInfo;
273 }
274
275
276 public Object getAttribute(String name)
277 {
278 if (_included)
279 {
280 if (name.equals(Dispatcher.__INCLUDE_REQUEST_URI))
281 return URIUtil.addPaths(URIUtil.addPaths(getContextPath(),_servletPath),_pathInfo);
282 if (name.equals(Dispatcher.__INCLUDE_PATH_INFO))
283 return _pathInfo;
284 if (name.equals(Dispatcher.__INCLUDE_SERVLET_PATH))
285 return _servletPath;
286 }
287 return super.getAttribute(name);
288 }
289 }
290
291
292 private ServletHolder getHolder(ServletHolder[] holders, String servlet)
293 {
294 if (holders == null)
295 return null;
296
297 ServletHolder holder = null;
298 for (int i=0; holder==null && i<holders.length; i++)
299 {
300 if (holders[i].getName().equals(servlet))
301 {
302 holder = holders[i];
303 }
304 }
305 return holder;
306 }
307 }