KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > module > sitemesh > filter > PageFilter


1 /* This software is published under the terms of the OpenSymphony Software
2  * License version 1.1, of which a copy has been included with this
3  * distribution in the LICENSE.txt file. */

4 package com.opensymphony.module.sitemesh.filter;
5
6 import com.opensymphony.module.sitemesh.*;
7 import com.opensymphony.module.sitemesh.util.Container;
8
9 import javax.servlet.*;
10 import javax.servlet.http.HttpServletRequest JavaDoc;
11 import javax.servlet.http.HttpServletResponse JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.PrintWriter JavaDoc;
14
15 /**
16  * Main SiteMesh filter for applying Decorators to entire Pages.
17  *
18  * @author <a HREF="joe@truemesh.com">Joe Walnes</a>
19  * @author <a HREF="scott@atlassian.com">Scott Farquhar</a>
20  * @version $Revision: 1.12 $
21  */

22 public class PageFilter implements Filter, RequestConstants {
23     private FilterConfig filterConfig = null;
24     private Factory factory = null;
25
26     /**
27      * Main method of the Filter.
28      *
29      * <p>Checks if the Filter has been applied this request. If not, parses the page
30      * and applies {@link com.opensymphony.module.sitemesh.Decorator} (if found).
31      */

32     public void doFilter(ServletRequest JavaDoc rq, ServletResponse JavaDoc rs, FilterChain chain)
33             throws IOException JavaDoc, ServletException {
34
35         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) rq;
36
37         if (rq.getAttribute(FILTER_APPLIED) != null || factory.isPathExcluded(extractRequestPath(request))) {
38             // ensure that filter is only applied once per request
39
chain.doFilter(rq, rs);
40         }
41         else {
42             request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
43
44             // force creation of the session now because Tomcat 4 had problems with
45
// creating sessions after the response had been committed
46
if (Container.get() == Container.TOMCAT) {
47                 request.getSession(true);
48             }
49             HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) rs;
50
51             // parse data into Page object (or continue as normal if Page not parseable)
52
Page page = parsePage(request, response, chain);
53
54             if (page != null) {
55                 page.setRequest(request);
56
57                 Decorator decorator = factory.getDecoratorMapper().getDecorator(request, page);
58                 if (decorator != null && decorator.getPage() != null) {
59                     applyDecorator(page, decorator, request, response);
60                     page = null;
61                     return;
62                 }
63
64                 // if we got here, an exception occured or the decorator was null,
65
// what we don't want is an exception printed to the user, so
66
// we write the original page
67
writeOriginal(request, response, page);
68                 page = null;
69             }
70         }
71     }
72
73     private String JavaDoc extractRequestPath(HttpServletRequest JavaDoc request) {
74         String JavaDoc servletPath = request.getServletPath();
75         String JavaDoc pathInfo = request.getPathInfo();
76         String JavaDoc query = request.getQueryString();
77         return (servletPath == null ? "" : servletPath)
78                 + (pathInfo == null ? "" : pathInfo)
79                 + (query == null ? "" : ("?" + query));
80     }
81
82     /** Set FilterConfig, and get instance of {@link com.opensymphony.module.sitemesh.DecoratorMapper}. */
83     public void init(FilterConfig filterConfig) {
84         if (filterConfig != null) {
85             this.filterConfig = filterConfig;
86             factory = Factory.getInstance(new Config(filterConfig));
87         }
88         else {
89             destroy();
90         }
91     }
92
93     /** @deprecated Not needed in final version of Servlet 2.3 API - replaced by init(). */
94     // NOTE: SiteMesh doesn't work with Orion 1.5.2 without this method
95
public FilterConfig getFilterConfig() {
96         return filterConfig;
97     }
98
99     /** @deprecated Not needed in final version of Servlet 2.3 API - replaced by init(). */
100     // NOTE: SiteMesh doesn't work with Orion 1.5.2 without this method
101
public void setFilterConfig(FilterConfig filterConfig) {
102         init(filterConfig);
103     }
104
105     /** Shutdown filter. */
106     public void destroy() {
107         factory = null;
108     }
109
110     /**
111      * Continue in filter-chain, writing all content to buffer and parsing
112      * into returned {@link com.opensymphony.module.sitemesh.Page} object. If
113      * {@link com.opensymphony.module.sitemesh.Page} is not parseable, null is returned.
114      */

115     protected Page parsePage(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, FilterChain chain) throws IOException JavaDoc, ServletException {
116         try {
117             PageResponseWrapper pageResponse = new PageResponseWrapper(response, factory);
118             chain.doFilter(request, pageResponse);
119             // check if another servlet or filter put a page object to the request
120
Page result = (Page)request.getAttribute(PAGE);
121             if (result == null) {
122                 // parse the page
123
result = pageResponse.getPage();
124             }
125             request.setAttribute(USING_STREAM, new Boolean JavaDoc(pageResponse.isUsingStream()));
126             return result;
127         }
128         catch (IllegalStateException JavaDoc e) {
129             // weblogic throws an IllegalStateException when an error page is served.
130
// it's ok to ignore this, however for all other containers it should be thrown
131
// properly.
132
if (Container.get() != Container.WEBLOGIC) throw e;
133             return null;
134         }
135     }
136
137     /**
138      * Apply {@link com.opensymphony.module.sitemesh.Decorator} to
139      * {@link com.opensymphony.module.sitemesh.Page} and write to the response.
140      */

141     protected void applyDecorator(Page page, Decorator decorator, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException, IOException JavaDoc {
142         try {
143             request.setAttribute(PAGE, page);
144             ServletContext context = filterConfig.getServletContext();
145             // see if the URI path (webapp) is set
146
if (decorator.getURIPath() != null) {
147                 // in a security conscious environment, the servlet container
148
// may return null for a given URL
149
if (context.getContext(decorator.getURIPath()) != null) {
150                     context = context.getContext(decorator.getURIPath());
151                 }
152             }
153             // get the dispatcher for the decorator
154
RequestDispatcher dispatcher = context.getRequestDispatcher(decorator.getPage());
155             // create a wrapper around the response
156
dispatcher.include(request, response);
157
158             // set the headers specified as decorator init params
159
while (decorator.getInitParameterNames().hasNext()) {
160                 String JavaDoc initParam = (String JavaDoc) decorator.getInitParameterNames().next();
161                 if (initParam.startsWith("header.")) {
162                     response.setHeader(initParam.substring(initParam.indexOf('.')), decorator.getInitParameter(initParam));
163                 }
164             }
165
166             request.removeAttribute(PAGE);
167         }
168         catch (RuntimeException JavaDoc e) {
169             // added a print message here because otherwise Tomcat swallows
170
// the error and you never see it = bad!
171
if (Container.get() == Container.TOMCAT)
172                 e.printStackTrace();
173
174             throw e;
175         }
176     }
177
178     /** Write the original page data to the response. */
179     private void writeOriginal(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, Page page) throws IOException JavaDoc {
180         response.setContentLength(page.getContentLength());
181         if (request.getAttribute(USING_STREAM).equals(Boolean.TRUE))
182         {
183             PrintWriter JavaDoc writer = new PrintWriter JavaDoc(response.getOutputStream());
184             page.writePage(writer);
185             //flush writer to underlying outputStream
186
writer.flush();
187             response.getOutputStream().flush();
188         }
189         else
190         {
191             page.writePage(response.getWriter());
192             response.getWriter().flush();
193         }
194     }
195 }
196
Popular Tags