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