KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > core > ApplicationFilterFactory


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.core;
20
21
22 import javax.servlet.Servlet JavaDoc;
23 import javax.servlet.ServletRequest JavaDoc;
24 import javax.servlet.http.HttpServletRequest JavaDoc;
25
26 import org.apache.catalina.CometFilter;
27 import org.apache.catalina.Globals;
28 import org.apache.catalina.Wrapper;
29 import org.apache.catalina.connector.Request;
30 import org.apache.catalina.deploy.FilterMap;
31
32 /**
33  * Factory for the creation and caching of Filters and creationg
34  * of Filter Chains.
35  *
36  * @author Greg Murray
37  * @author Remy Maucherat
38  * @version $Revision: 1.0
39  */

40
41 public final class ApplicationFilterFactory {
42
43
44     // -------------------------------------------------------------- Constants
45

46
47     public static final int ERROR = 1;
48     public static final Integer JavaDoc ERROR_INTEGER = new Integer JavaDoc(ERROR);
49     public static final int FORWARD = 2;
50     public static final Integer JavaDoc FORWARD_INTEGER = new Integer JavaDoc(FORWARD);
51     public static final int INCLUDE = 4;
52     public static final Integer JavaDoc INCLUDE_INTEGER = new Integer JavaDoc(INCLUDE);
53     public static final int REQUEST = 8;
54     public static final Integer JavaDoc REQUEST_INTEGER = new Integer JavaDoc(REQUEST);
55
56     public static final String JavaDoc DISPATCHER_TYPE_ATTR =
57         Globals.DISPATCHER_TYPE_ATTR;
58     public static final String JavaDoc DISPATCHER_REQUEST_PATH_ATTR =
59         Globals.DISPATCHER_REQUEST_PATH_ATTR;
60
61     private static final SecurityManager JavaDoc securityManager =
62         System.getSecurityManager();
63
64     private static ApplicationFilterFactory factory = null;;
65
66
67     // ----------------------------------------------------------- Constructors
68

69
70     /*
71      * Prevent instanciation outside of the getInstanceMethod().
72      */

73     private ApplicationFilterFactory() {
74     }
75
76
77     // --------------------------------------------------------- Public Methods
78

79
80     /**
81      * Return the fqctory instance.
82      */

83     public static ApplicationFilterFactory getInstance() {
84         if (factory == null) {
85             factory = new ApplicationFilterFactory();
86         }
87         return factory;
88     }
89
90
91     /**
92      * Construct and return a FilterChain implementation that will wrap the
93      * execution of the specified servlet instance. If we should not execute
94      * a filter chain at all, return <code>null</code>.
95      *
96      * @param request The servlet request we are processing
97      * @param servlet The servlet instance to be wrapped
98      */

99     public ApplicationFilterChain createFilterChain
100         (ServletRequest JavaDoc request, Wrapper wrapper, Servlet JavaDoc servlet) {
101
102         // get the dispatcher type
103
int dispatcher = -1;
104         if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
105             Integer JavaDoc dispatcherInt =
106                 (Integer JavaDoc) request.getAttribute(DISPATCHER_TYPE_ATTR);
107             dispatcher = dispatcherInt.intValue();
108         }
109         String JavaDoc requestPath = null;
110         Object JavaDoc attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR);
111         
112         if (attribute != null){
113             requestPath = attribute.toString();
114         }
115         
116         HttpServletRequest JavaDoc hreq = null;
117         if (request instanceof HttpServletRequest JavaDoc)
118             hreq = (HttpServletRequest JavaDoc)request;
119         // If there is no servlet to execute, return null
120
if (servlet == null)
121             return (null);
122
123         boolean comet = false;
124         
125         // Create and initialize a filter chain object
126
ApplicationFilterChain filterChain = null;
127         if ((securityManager == null) && (request instanceof Request JavaDoc)) {
128             Request JavaDoc req = (Request JavaDoc) request;
129             filterChain = (ApplicationFilterChain) req.getFilterChain();
130             if (filterChain == null) {
131                 filterChain = new ApplicationFilterChain();
132                 req.setFilterChain(filterChain);
133             }
134             comet = req.isComet();
135         } else {
136             // Security: Do not recycle
137
filterChain = new ApplicationFilterChain();
138         }
139
140         filterChain.setServlet(servlet);
141
142         filterChain.setSupport
143             (((StandardWrapper)wrapper).getInstanceSupport());
144
145         // Acquire the filter mappings for this Context
146
StandardContext context = (StandardContext) wrapper.getParent();
147         FilterMap filterMaps[] = context.findFilterMaps();
148
149         // If there are no filter mappings, we are done
150
if ((filterMaps == null) || (filterMaps.length == 0))
151             return (filterChain);
152
153         // Acquire the information we will need to match filter mappings
154
String JavaDoc servletName = wrapper.getName();
155
156         // Add the relevant path-mapped filters to this filter chain
157
for (int i = 0; i < filterMaps.length; i++) {
158             if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
159                 continue;
160             }
161             if (!matchFiltersURL(filterMaps[i], requestPath))
162                 continue;
163             ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
164                 context.findFilterConfig(filterMaps[i].getFilterName());
165             if (filterConfig == null) {
166                 ; // FIXME - log configuration problem
167
continue;
168             }
169             boolean isCometFilter = false;
170             if (comet) {
171                 try {
172                     isCometFilter = filterConfig.getFilter() instanceof CometFilter;
173                 } catch (Exception JavaDoc e) {
174                     // Note: The try catch is there because getFilter has a lot of
175
// declared exceptions. However, the filter is allocated much
176
// earlier
177
}
178                 if (isCometFilter) {
179                     filterChain.addFilter(filterConfig);
180                 }
181             } else {
182                 filterChain.addFilter(filterConfig);
183             }
184         }
185
186         // Add filters that match on servlet name second
187
for (int i = 0; i < filterMaps.length; i++) {
188             if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
189                 continue;
190             }
191             if (!matchFiltersServlet(filterMaps[i], servletName))
192                 continue;
193             ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
194                 context.findFilterConfig(filterMaps[i].getFilterName());
195             if (filterConfig == null) {
196                 ; // FIXME - log configuration problem
197
continue;
198             }
199             boolean isCometFilter = false;
200             if (comet) {
201                 try {
202                     isCometFilter = filterConfig.getFilter() instanceof CometFilter;
203                 } catch (Exception JavaDoc e) {
204                     // Note: The try catch is there because getFilter has a lot of
205
// declared exceptions. However, the filter is allocated much
206
// earlier
207
}
208                 if (isCometFilter) {
209                     filterChain.addFilter(filterConfig);
210                 }
211             } else {
212                 filterChain.addFilter(filterConfig);
213             }
214         }
215
216         // Return the completed filter chain
217
return (filterChain);
218
219     }
220
221
222     // -------------------------------------------------------- Private Methods
223

224
225     /**
226      * Return <code>true</code> if the context-relative request path
227      * matches the requirements of the specified filter mapping;
228      * otherwise, return <code>false</code>.
229      *
230      * @param filterMap Filter mapping being checked
231      * @param requestPath Context-relative request path of this request
232      */

233     private boolean matchFiltersURL(FilterMap filterMap, String JavaDoc requestPath) {
234
235         // Check the specific "*" special URL pattern, which also matches
236
// named dispatches
237
if (filterMap.getAllMatch())
238             return (true);
239         
240         if (requestPath == null)
241             return (false);
242
243         // Match on context relative request path
244
String JavaDoc[] testPaths = filterMap.getURLPatterns();
245         
246         for (int i = 0; i < testPaths.length; i++) {
247             if (matchFiltersURL(testPaths[i], requestPath)) {
248                 return (true);
249             }
250         }
251         
252         // No match
253
return (false);
254         
255     }
256     
257
258     /**
259      * Return <code>true</code> if the context-relative request path
260      * matches the requirements of the specified filter mapping;
261      * otherwise, return <code>false</code>.
262      *
263      * @param testPath URL mapping being checked
264      * @param requestPath Context-relative request path of this request
265      */

266     private boolean matchFiltersURL(String JavaDoc testPath, String JavaDoc requestPath) {
267         
268         if (testPath == null)
269             return (false);
270
271         // Case 1 - Exact Match
272
if (testPath.equals(requestPath))
273             return (true);
274
275         // Case 2 - Path Match ("/.../*")
276
if (testPath.equals("/*"))
277             return (true);
278         if (testPath.endsWith("/*")) {
279             if (testPath.regionMatches(0, requestPath, 0,
280                                        testPath.length() - 2)) {
281                 if (requestPath.length() == (testPath.length() - 2)) {
282                     return (true);
283                 } else if ('/' == requestPath.charAt(testPath.length() - 2)) {
284                     return (true);
285                 }
286             }
287             return (false);
288         }
289
290         // Case 3 - Extension Match
291
if (testPath.startsWith("*.")) {
292             int slash = requestPath.lastIndexOf('/');
293             int period = requestPath.lastIndexOf('.');
294             if ((slash >= 0) && (period > slash)
295                 && (period != requestPath.length() - 1)
296                 && ((requestPath.length() - period)
297                     == (testPath.length() - 1))) {
298                 return (testPath.regionMatches(2, requestPath, period + 1,
299                                                testPath.length() - 2));
300             }
301         }
302
303         // Case 4 - "Default" Match
304
return (false); // NOTE - Not relevant for selecting filters
305

306     }
307
308
309     /**
310      * Return <code>true</code> if the specified servlet name matches
311      * the requirements of the specified filter mapping; otherwise
312      * return <code>false</code>.
313      *
314      * @param filterMap Filter mapping being checked
315      * @param servletName Servlet name being checked
316      */

317     private boolean matchFiltersServlet(FilterMap filterMap,
318                                         String JavaDoc servletName) {
319
320         if (servletName == null) {
321             return (false);
322         } else {
323             String JavaDoc[] servletNames = filterMap.getServletNames();
324             for (int i = 0; i < servletNames.length; i++) {
325                 if (servletName.equals(servletNames[i])) {
326                     return (true);
327                 }
328             }
329             return false;
330         }
331
332     }
333
334
335     /**
336      * Convienience method which returns true if the dispatcher type
337      * matches the dispatcher types specified in the FilterMap
338      */

339     private boolean matchDispatcher(FilterMap filterMap, int dispatcher) {
340         switch (dispatcher) {
341             case FORWARD : {
342                 if (filterMap.getDispatcherMapping() == FilterMap.FORWARD ||
343                     filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR ||
344                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD ||
345                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
346                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD ||
347                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
348                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
349                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) {
350                         return true;
351                 }
352                 break;
353             }
354             case INCLUDE : {
355                 if (filterMap.getDispatcherMapping() == FilterMap.INCLUDE ||
356                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR ||
357                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_FORWARD ||
358                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
359                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE ||
360                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE ||
361                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
362                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE) {
363                         return true;
364                 }
365                 break;
366             }
367             case REQUEST : {
368                 if (filterMap.getDispatcherMapping() == FilterMap.REQUEST ||
369                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR ||
370                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_INCLUDE ||
371                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE ||
372                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD ||
373                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
374                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_FORWARD_INCLUDE ||
375                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE) {
376                         return true;
377                 }
378                 break;
379             }
380             case ERROR : {
381                 if (filterMap.getDispatcherMapping() == FilterMap.ERROR ||
382                     filterMap.getDispatcherMapping() == FilterMap.FORWARD_ERROR ||
383                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR ||
384                     filterMap.getDispatcherMapping() == FilterMap.INCLUDE_ERROR_FORWARD ||
385                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR ||
386                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD ||
387                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_FORWARD_INCLUDE ||
388                     filterMap.getDispatcherMapping() == FilterMap.REQUEST_ERROR_INCLUDE) {
389                         return true;
390                 }
391                 break;
392             }
393         }
394         return false;
395     }
396
397
398 }
399
Popular Tags