KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > dispatch > ServletMapper


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.server.dispatch;
31
32 import com.caucho.log.Log;
33 import com.caucho.make.DependencyContainer;
34 import com.caucho.server.webapp.WebApp;
35 import com.caucho.util.L10N;
36 import com.caucho.vfs.Depend;
37 import com.caucho.vfs.Path;
38
39 import javax.servlet.FilterChain JavaDoc;
40 import javax.servlet.ServletContext JavaDoc;
41 import javax.servlet.ServletException JavaDoc;
42 import java.io.InputStream JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.logging.Level JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 /**
49  * Manages dispatching: servlets and filters.
50  */

51 public class ServletMapper {
52   static final Logger JavaDoc log = Log.open(ServletMapper.class);
53   static final L10N L = new L10N(ServletMapper.class);
54
55   private ServletContext JavaDoc _servletContext;
56   
57   private ServletManager _servletManager;
58   
59   private UrlMap<String JavaDoc> _servletMap = new UrlMap<String JavaDoc>();
60   
61   private ArrayList JavaDoc<String JavaDoc> _welcomeFileList = new ArrayList JavaDoc<String JavaDoc>();
62   
63   private HashMap JavaDoc<String JavaDoc,ServletMapping> _regexpMap
64     = new HashMap JavaDoc<String JavaDoc,ServletMapping>();
65   
66   private ArrayList JavaDoc<String JavaDoc> _ignorePatterns = new ArrayList JavaDoc<String JavaDoc>();
67   
68   private String JavaDoc _defaultServlet;
69
70   /**
71    * Sets the servlet context.
72    */

73   public void setServletContext(ServletContext JavaDoc servletContext)
74   {
75     _servletContext = servletContext;
76   }
77
78   /**
79    * Gets the servlet context.
80    */

81   public ServletContext JavaDoc getServletContext()
82   {
83     return _servletContext;
84   }
85
86   /**
87    * Returns the servlet manager.
88    */

89   public ServletManager getServletManager()
90   {
91     return _servletManager;
92   }
93
94   /**
95    * Sets the servlet manager.
96    */

97   public void setServletManager(ServletManager manager)
98   {
99     _servletManager = manager;
100   }
101
102   /**
103    * Adds a servlet mapping
104    */

105   public void addUrlRegexp(String JavaDoc regexp, ServletMapping mapping)
106     throws ServletException JavaDoc
107   {
108     _servletMap.addRegexp(regexp, regexp);
109     _regexpMap.put(regexp, mapping);
110   }
111
112   /**
113    * Adds a servlet mapping
114    */

115   void addUrlMapping(String JavaDoc urlPattern,
116              String JavaDoc servletName,
117              ServletMapping mapping)
118     throws ServletException JavaDoc
119   {
120     try {
121       if (servletName == null) {
122     throw new ServletConfigException(L.l("servlet needs a servlet-name."));
123       }
124       else if (servletName.equals("invoker")) {
125         // special case
126
}
127       else if (servletName.equals("plugin_match") ||
128            servletName.equals("plugin-match")) {
129         // special case
130
}
131       else if (servletName.equals("plugin_ignore") ||
132            servletName.equals("plugin-ignore")) {
133     if (urlPattern != null)
134       _ignorePatterns.add(urlPattern);
135     
136     return;
137       }
138       else if (_servletManager.getServlet(servletName) == null)
139         throw new ServletConfigException(L.l("`{0}' is an unknown servlet-name. servlet-mapping requires that the named servlet be defined in a <servlet> configuration before the <servlet-mapping>.", servletName));
140
141       if ("/".equals(urlPattern)) {
142         _defaultServlet = servletName;
143       }
144       else if (mapping.isStrictMapping()) {
145         _servletMap.addStrictMap(urlPattern, null, servletName);
146       }
147       else
148         _servletMap.addMap(urlPattern, servletName);
149
150       log.config("servlet-mapping " + urlPattern + " -> " + servletName);
151     } catch (ServletException JavaDoc e) {
152       throw e;
153     } catch (Exception JavaDoc e) {
154       throw new ServletException JavaDoc(e);
155     }
156   }
157
158   /**
159    * Adds a servlet mapping
160    */

161   /*
162   public void addServletRegexp(ServletMapping servletRegexp)
163     throws ServletException
164   {
165     try {
166       String regexp = servletRegexp.getURLRegexp();
167
168       _servletMap.addRegexp(regexp, regexp);
169       _regexpMap.put(regexp, servletRegexp);
170     } catch (RuntimeException e) {
171       throw e;
172     } catch (Exception e) {
173       throw new ServletException(e);
174     }
175   }
176   */

177   
178   /**
179    * Sets the default servlet.
180    */

181   public void setDefaultServlet(String JavaDoc servletName)
182     throws ServletException JavaDoc
183   {
184     _defaultServlet = servletName;
185   }
186   
187   /**
188    * Adds a welcome-file
189    */

190   public void addWelcomeFile(String JavaDoc fileName)
191   {
192     _welcomeFileList.add(fileName);
193   }
194   
195   /**
196    * Sets the welcome-file list
197    */

198   public void setWelcomeFileList(ArrayList JavaDoc<String JavaDoc> list)
199   {
200     _welcomeFileList.clear();
201     _welcomeFileList.addAll(list);
202   }
203
204   public FilterChain JavaDoc mapServlet(ServletInvocation invocation)
205     throws ServletException JavaDoc
206   {
207     String JavaDoc contextURI = invocation.getContextURI();
208
209     String JavaDoc servletName = null;
210     ArrayList JavaDoc<String JavaDoc> vars = new ArrayList JavaDoc<String JavaDoc>();
211
212     invocation.setClassLoader(Thread.currentThread().getContextClassLoader());
213
214     if (_servletMap != null) {
215       servletName = _servletMap.map(contextURI, vars);
216
217       ServletMapping servletRegexp = _regexpMap.get(servletName);
218
219       if (servletRegexp != null) {
220     servletName = servletRegexp.initRegexp(_servletContext,
221                            _servletManager,
222                            vars);
223       }
224     }
225
226     if (servletName == null) {
227       try {
228         InputStream JavaDoc is;
229         is = _servletContext.getResourceAsStream(contextURI);
230
231         if (is != null) {
232           is.close();
233
234           servletName = _defaultServlet;
235         }
236       } catch (Exception JavaDoc e) {
237       }
238     }
239
240     if (servletName == null) {
241       for (int i = 0; i < _welcomeFileList.size(); i++) {
242         String JavaDoc file = _welcomeFileList.get(i);
243
244         try {
245       String JavaDoc welcomeURI;
246
247       if (contextURI.endsWith("/"))
248         welcomeURI = contextURI + file;
249       else
250         welcomeURI = contextURI + '/' + file;
251
252           InputStream JavaDoc is;
253           is = _servletContext.getResourceAsStream(welcomeURI);
254
255           if (is != null)
256             is.close();
257           
258           if (is == null) {
259           }
260           else if (! contextURI.endsWith("/") &&
261            ! (invocation instanceof SubInvocation)) {
262             String JavaDoc contextPath = invocation.getContextPath();
263
264         return new RedirectFilterChain(contextPath + contextURI + "/");
265           }
266           else {
267             servletName = _servletMap.map(welcomeURI, vars);
268
269             if (servletName != null || _defaultServlet != null) {
270               contextURI = welcomeURI;
271               if (invocation instanceof Invocation) {
272                 Invocation inv = (Invocation) invocation;
273
274                 inv.setContextURI(contextURI);
275                 inv.setRawURI(inv.getRawURI() + file);
276               }
277               break;
278             }
279           }
280         } catch (Throwable JavaDoc e) {
281         }
282       }
283     }
284
285     if (servletName == null) {
286       servletName = _defaultServlet;
287       vars.clear();
288       vars.add(contextURI);
289
290       addWelcomeFileDependency(invocation);
291     }
292
293     if (servletName == null) {
294       log.fine(L.l("no default servlet defined for URL: '{0}'", contextURI));
295       
296       return new ErrorFilterChain(404);
297     }
298
299     String JavaDoc servletPath = vars.get(0);
300
301     invocation.setServletPath(servletPath);
302
303     if (servletPath.length() < contextURI.length())
304       invocation.setPathInfo(contextURI.substring(servletPath.length()));
305     else
306       invocation.setPathInfo(null);
307
308     ServletMapping regexp = _regexpMap.get(servletName);
309
310     if (regexp != null)
311       servletName = regexp.initRegexp(_servletContext, _servletManager, vars);
312
313     if (servletName.equals("invoker"))
314       servletName = handleInvoker(invocation);
315
316     invocation.setServletName(servletName);
317     
318     if (log.isLoggable(Level.FINE))
319       log.fine("invoke (uri:" + contextURI + " -> " + servletName + ")");
320
321     ServletConfigImpl config = _servletManager.getServlet(servletName);
322
323     if (config != null)
324       invocation.setSecurityRoleMap(config.getRoleMap());
325
326     FilterChain JavaDoc chain = _servletManager.createServletChain(servletName);
327
328     if (chain instanceof PageFilterChain) {
329       PageFilterChain pageChain = (PageFilterChain) chain;
330
331       chain = PrecompilePageFilterChain.create(invocation, pageChain);
332     }
333
334     return chain;
335   }
336
337   private void addWelcomeFileDependency(ServletInvocation servletInvocation)
338   {
339     if (! (servletInvocation instanceof Invocation))
340       return;
341
342     Invocation invocation = (Invocation) servletInvocation;
343     
344     String JavaDoc contextURI = invocation.getContextURI();
345
346     DependencyContainer dependencyList = new DependencyContainer();
347
348     WebApp app = (WebApp) _servletContext;
349     
350     for (int i = 0; i < _welcomeFileList.size(); i++) {
351       String JavaDoc file = _welcomeFileList.get(i);
352
353       String JavaDoc realPath = app.getRealPath(contextURI + "/" + file);
354
355       Path path = app.getAppDir().lookup(realPath);
356
357       dependencyList.add(new Depend(path));
358     }
359
360     dependencyList.clearModified();
361
362     invocation.setDependency(dependencyList);
363   }
364   
365   private String JavaDoc handleInvoker(ServletInvocation invocation)
366     throws ServletException JavaDoc
367   {
368     String JavaDoc tail;
369     
370     if (invocation.getPathInfo() != null)
371       tail = invocation.getPathInfo();
372     else
373       tail = invocation.getServletPath();
374
375       // XXX: this is really an unexpected, internal error that should never
376
// happen
377
if (! tail.startsWith("/")) {
378       throw new ServletException JavaDoc("expected '/' starting " +
379                                  " sp:" + invocation.getServletPath() +
380                                  " pi:" + invocation.getPathInfo() +
381                                  " sn:invocation" + invocation);
382     }
383
384     int next = tail.indexOf('/', 1);
385     String JavaDoc servletName;
386
387     if (next < 0)
388       servletName = tail.substring(1);
389     else
390       servletName = tail.substring(1, next);
391
392     // XXX: This should be generalized, possibly with invoker configuration
393
if (servletName.startsWith("com.caucho")) {
394       throw new ServletConfigException(L.l("servlet `{0}' forbidden from invoker. com.caucho.* classes must be defined explicitly in a <servlet> declaration.",
395                                      servletName));
396     }
397     else if (servletName.equals("")) {
398       throw new ServletConfigException(L.l("invoker needs a servlet name in URL `{0}'.",
399                                            invocation.getContextURI()));
400     }
401       
402     addServlet(servletName);
403
404     String JavaDoc servletPath = invocation.getServletPath();
405     if (invocation.getPathInfo() == null) {
406     }
407     else if (next < 0) {
408       invocation.setServletPath(servletPath + tail);
409       invocation.setPathInfo(null);
410     }
411     else if (next < tail.length()) {
412       
413       invocation.setServletPath(servletPath + tail.substring(0, next));
414       invocation.setPathInfo(tail.substring(next));
415     }
416     else {
417       invocation.setServletPath(servletPath + tail);
418       invocation.setPathInfo(null);
419     }
420
421     return servletName;
422   }
423
424   public String JavaDoc getServletPattern(String JavaDoc uri)
425   {
426     ArrayList JavaDoc<String JavaDoc> vars = new ArrayList JavaDoc<String JavaDoc>();
427
428     Object JavaDoc value = null;
429     
430     if (_servletMap != null)
431       value = _servletMap.map(uri, vars);
432
433     if (value == null)
434       return null;
435     else
436       return uri;
437   }
438
439   /**
440    * Returns the servlet matching patterns.
441    */

442   public ArrayList JavaDoc<String JavaDoc> getURLPatterns()
443   {
444     ArrayList JavaDoc<String JavaDoc> patterns = _servletMap.getURLPatterns();
445
446     return patterns;
447   }
448
449   /**
450    * Returns the servlet plugin_ignore patterns.
451    */

452   public ArrayList JavaDoc<String JavaDoc> getIgnorePatterns()
453   {
454     return _ignorePatterns;
455   }
456
457   private void addServlet(String JavaDoc servletName)
458     throws ServletException JavaDoc
459   {
460     if (_servletManager.getServlet(servletName) != null)
461       return;
462
463     ServletConfigImpl config = new ServletConfigImpl();
464     config.setServletContext(_servletContext);
465     config.setServletName(servletName);
466
467     try {
468       config.setServletClass(servletName);
469     } catch (Exception JavaDoc e) {
470       throw new ServletException JavaDoc(e);
471     }
472
473     config.init();
474
475     _servletManager.addServlet(config);
476   }
477     
478   public void destroy()
479   {
480     _servletManager.destroy();
481   }
482 }
483
Popular Tags