KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > jetty > servlet > Invoker


1 // ========================================================================
2
// $Id: Invoker.java,v 1.15 2005/08/13 00:01:27 gregwilkins Exp $
3
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.jetty.servlet;
17
18
19 import java.io.IOException JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import javax.servlet.ServletContext JavaDoc;
25 import javax.servlet.ServletException JavaDoc;
26 import javax.servlet.UnavailableException JavaDoc;
27 import javax.servlet.http.HttpServlet JavaDoc;
28 import javax.servlet.http.HttpServletRequest JavaDoc;
29 import javax.servlet.http.HttpServletRequestWrapper JavaDoc;
30 import javax.servlet.http.HttpServletResponse JavaDoc;
31
32 import org.apache.commons.logging.Log;
33 import org.mortbay.log.LogFactory;
34 import org.mortbay.util.LogSupport;
35 import org.mortbay.util.URI;
36
37 /* ------------------------------------------------------------ */
38 /** Dynamic Servlet Invoker.
39  * This servlet invokes anonymous servlets that have not been defined
40  * in the web.xml or by other means. The first element of the pathInfo
41  * of a request passed to the envoker is treated as a servlet name for
42  * an existing servlet, or as a class name of a new servlet.
43  * This servlet is normally mapped to /servlet/*
44  * This servlet support the following initParams:
45  * <PRE>
46  * nonContextServlets If false, the invoker can only load
47  * servlets from the contexts classloader.
48  * This is false by default and setting this
49  * to true may have security implications.
50  *
51  * verbose If true, log dynamic loads
52  *
53  * * All other parameters are copied to the
54  * each dynamic servlet as init parameters
55  * </PRE>
56  * @version $Id: Invoker.java,v 1.15 2005/08/13 00:01:27 gregwilkins Exp $
57  * @author Greg Wilkins (gregw)
58  */

59 public class Invoker extends HttpServlet JavaDoc
60 {
61     private static Log log = LogFactory.getLog(Invoker.class);
62
63     private ServletHandler _servletHandler;
64     private Map.Entry JavaDoc _invokerEntry;
65     private Map JavaDoc _parameters;
66     private boolean _nonContextServlets;
67     private boolean _verbose;
68         
69     /* ------------------------------------------------------------ */
70     public void init()
71     {
72         ServletContext JavaDoc config=getServletContext();
73         _servletHandler=((ServletHandler.Context)config).getServletHandler();
74
75         Enumeration JavaDoc e = getInitParameterNames();
76         while(e.hasMoreElements())
77         {
78             String JavaDoc param=(String JavaDoc)e.nextElement();
79             String JavaDoc value=getInitParameter(param);
80             String JavaDoc lvalue=value.toLowerCase();
81             if ("nonContextServlets".equals(param))
82             {
83                 _nonContextServlets=value.length()>0 && lvalue.startsWith("t");
84             }
85             if ("verbose".equals(param))
86             {
87                 _verbose=value.length()>0 && lvalue.startsWith("t");
88             }
89             else
90             {
91                 if (_parameters==null)
92                     _parameters=new HashMap JavaDoc();
93                 _parameters.put(param,value);
94             }
95         }
96     }
97     
98     /* ------------------------------------------------------------ */
99     protected void service(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
100     throws ServletException JavaDoc, IOException JavaDoc
101     {
102         // Get the requested path and info
103
boolean included=false;
104         String JavaDoc servlet_path=(String JavaDoc)request.getAttribute(Dispatcher.__INCLUDE_SERVLET_PATH);
105         if (servlet_path==null)
106             servlet_path=request.getServletPath();
107         else
108             included=true;
109         String JavaDoc path_info = (String JavaDoc)request.getAttribute(Dispatcher.__INCLUDE_PATH_INFO);
110         if (path_info==null)
111             path_info=request.getPathInfo();
112         
113         // Get the servlet class
114
String JavaDoc servlet = path_info;
115         if (servlet==null || servlet.length()<=1 )
116         {
117             response.sendError(404);
118             return;
119         }
120         
121         int i0=servlet.charAt(0)=='/'?1:0;
122         int i1=servlet.indexOf('/',i0);
123         servlet=i1<0?servlet.substring(i0):servlet.substring(i0,i1);
124
125         // look for a named holder
126
ServletHolder holder=_servletHandler.getServletHolder(servlet);
127         if (holder!=null)
128         {
129             // Add named servlet mapping
130
_servletHandler.addServletHolder(holder);
131             _servletHandler.mapPathToServlet(URI.addPaths(servlet_path,servlet)+"/*", holder.getName());
132         }
133         else
134         {
135             // look for a class mapping
136
if (servlet.endsWith(".class"))
137                 servlet=servlet.substring(0,servlet.length()-6);
138             if (servlet==null || servlet.length()==0)
139             {
140                 response.sendError(404);
141                 return;
142             }
143         
144             synchronized(_servletHandler)
145             {
146                 // find the entry for the invoker
147
if (_invokerEntry==null)
148                     _invokerEntry=_servletHandler.getHolderEntry(servlet_path);
149             
150                 // Check for existing mapping (avoid threaded race).
151
String JavaDoc path=URI.addPaths(servlet_path,servlet);
152                 Map.Entry JavaDoc entry = _servletHandler.getHolderEntry(path);
153
154                 if (entry!=null && entry!=_invokerEntry)
155                 {
156                     // Use the holder
157
holder=(ServletHolder)entry.getValue();
158                 }
159                 else
160                 {
161                     // Make a holder
162
holder=new ServletHolder(_servletHandler,servlet,servlet);
163                     
164                     if (_parameters!=null)
165                         holder.putAll(_parameters);
166                     
167                     try {holder.start();}
168                     catch (Exception JavaDoc e)
169                     {
170                         log.debug(LogSupport.EXCEPTION,e);
171                         throw new UnavailableException JavaDoc(e.toString());
172                     }
173                     
174                     // Check it is from an allowable classloader
175
if (!_nonContextServlets)
176                     {
177                         Object JavaDoc s=holder.getServlet();
178                         
179                         if (_servletHandler.getClassLoader()!=
180                             s.getClass().getClassLoader())
181                         {
182                             holder.stop();
183                             log.warn("Dynamic servlet "+s+
184                                          " not loaded from context "+
185                                          request.getContextPath());
186                             throw new UnavailableException JavaDoc("Not in context");
187                         }
188                     }
189
190                     // Add the holder for all the possible paths
191
if (_verbose)
192                         log("Dynamic load '"+servlet+"' at "+path);
193                     _servletHandler.addServletHolder(holder);
194                     _servletHandler.mapPathToServlet(path+"/*",holder.getName());
195                     _servletHandler.mapPathToServlet(path+".class/*",holder.getName());
196                 }
197             }
198             
199         }
200         
201         if (holder!=null)
202             holder.handle(new Request JavaDoc(request,included,servlet,servlet_path,path_info),
203                           response);
204         else
205             response.sendError(404);
206         
207     }
208
209     /* ------------------------------------------------------------ */
210     class Request extends HttpServletRequestWrapper JavaDoc
211     {
212         String JavaDoc _servletPath;
213         String JavaDoc _pathInfo;
214         boolean _included;
215         
216         /* ------------------------------------------------------------ */
217         Request(HttpServletRequest JavaDoc request,
218                 boolean included,
219                 String JavaDoc name,
220                 String JavaDoc servletPath,
221                 String JavaDoc pathInfo)
222         {
223             super(request);
224             _included=included;
225             _servletPath=URI.addPaths(servletPath,name);
226             _pathInfo=pathInfo.substring(name.length()+1);
227             if (_pathInfo.length()==0)
228                 _pathInfo=null;
229         }
230         
231         /* ------------------------------------------------------------ */
232         public String JavaDoc getServletPath()
233         {
234             if (_included)
235                 return super.getServletPath();
236             return _servletPath;
237         }
238         
239         /* ------------------------------------------------------------ */
240         public String JavaDoc getPathInfo()
241         {
242             if (_included)
243                 return super.getPathInfo();
244             return _pathInfo;
245         }
246         
247         /* ------------------------------------------------------------ */
248         public Object JavaDoc getAttribute(String JavaDoc name)
249         {
250             if (_included)
251             {
252                 if (name.equals(Dispatcher.__INCLUDE_REQUEST_URI))
253                     return URI.addPaths(URI.addPaths(getContextPath(),_servletPath),_pathInfo);
254                 if (name.equals(Dispatcher.__INCLUDE_PATH_INFO))
255                     return _pathInfo;
256                 if (name.equals(Dispatcher.__INCLUDE_SERVLET_PATH))
257                     return _servletPath;
258             }
259             return super.getAttribute(name);
260         }
261     }
262 }
263
Popular Tags