• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / sitemesh2 / 59

22 Mar 2026 02:30AM UTC coverage: 40.347%. Remained the same
59

push

github

hazendaz
[mvn] Update maven wrapper

698 of 1891 branches covered (36.91%)

Branch coverage included in aggregate %.

1555 of 3693 relevant lines covered (42.11%)

0.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/com/opensymphony/sitemesh/webapp/SiteMeshFilter.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2011-2026 Hazendaz
4
 */
5
package com.opensymphony.sitemesh.webapp;
6

7
import com.opensymphony.module.sitemesh.Config;
8
import com.opensymphony.module.sitemesh.Factory;
9
import com.opensymphony.sitemesh.Content;
10
import com.opensymphony.sitemesh.ContentProcessor;
11
import com.opensymphony.sitemesh.Decorator;
12
import com.opensymphony.sitemesh.DecoratorSelector;
13
import com.opensymphony.sitemesh.compatability.DecoratorMapper2DecoratorSelector;
14
import com.opensymphony.sitemesh.compatability.PageParser2ContentProcessor;
15

16
import jakarta.servlet.Filter;
17
import jakarta.servlet.FilterChain;
18
import jakarta.servlet.FilterConfig;
19
import jakarta.servlet.ServletContext;
20
import jakarta.servlet.ServletException;
21
import jakarta.servlet.ServletRequest;
22
import jakarta.servlet.ServletResponse;
23
import jakarta.servlet.http.HttpServletRequest;
24
import jakarta.servlet.http.HttpServletResponse;
25

26
import java.io.IOException;
27

28
/**
29
 * Core Filter for integrating SiteMesh into a Java web application.
30
 *
31
 * @author Joe Walnes
32
 * @author Scott Farquhar
33
 *
34
 * @since SiteMesh 3
35
 */
36
public class SiteMeshFilter implements Filter {
×
37

38
    /** The filter config. */
39
    private FilterConfig filterConfig;
40

41
    /** The container tweaks. */
42
    private ContainerTweaks containerTweaks;
43

44
    /** The Constant ALREADY_APPLIED_KEY. */
45
    private static final String ALREADY_APPLIED_KEY = "com.opensymphony.sitemesh.APPLIED_ONCE";
46

47
    @Override
48
    public void init(FilterConfig filterConfig) {
49
        this.filterConfig = filterConfig;
×
50
        containerTweaks = new ContainerTweaks();
×
51
    }
×
52

53
    @Override
54
    public void destroy() {
55
        filterConfig = null;
×
56
        containerTweaks = null;
×
57
    }
×
58

59
    /**
60
     * Main method of the Filter.
61
     * <p>
62
     * Checks if the Filter has been applied this request. If not, parses the page and applies
63
     * {@link com.opensymphony.module.sitemesh.Decorator} (if found).
64
     */
65
    @Override
66
    public void doFilter(ServletRequest rq, ServletResponse rs, FilterChain chain)
67
            throws IOException, ServletException {
68

69
        HttpServletRequest request = (HttpServletRequest) rq;
×
70
        HttpServletResponse response = (HttpServletResponse) rs;
×
71
        ServletContext servletContext = filterConfig.getServletContext();
×
72

73
        SiteMeshWebAppContext webAppContext = new SiteMeshWebAppContext(request, response, servletContext);
×
74

75
        ContentProcessor contentProcessor = initContentProcessor(webAppContext);
×
76
        DecoratorSelector decoratorSelector = initDecoratorSelector(webAppContext);
×
77

78
        if (filterAlreadyAppliedForRequest(request) || !contentProcessor.handles(webAppContext)) {
×
79
            // Optimization: If the content doesn't need to be processed, bypass SiteMesh.
80
            chain.doFilter(request, response);
×
81
            return;
×
82
        }
83

84
        if (containerTweaks.shouldAutoCreateSession()) {
×
85
            // Some containers (such as Tomcat 4) will not allow sessions to be created in the decorator.
86
            // (i.e after the response has been committed).
87
            request.getSession(true);
×
88
        }
89

90
        try {
91

92
            Content content = obtainContent(contentProcessor, webAppContext, request, response, chain);
×
93

94
            if (content == null) {
×
95
                request.setAttribute(ALREADY_APPLIED_KEY, null);
×
96
                return;
×
97
            }
98

99
            Decorator decorator = decoratorSelector.selectDecorator(content, webAppContext);
×
100
            decorator.render(content, webAppContext);
×
101

102
        } catch (IllegalStateException e) {
×
103
            // Some containers (such as WebLogic) throw an IllegalStateException when an error page is served.
104
            // It may be ok to ignore this. However, for safety it is propegated if possible.
105
            if (!containerTweaks.shouldIgnoreIllegalStateExceptionOnErrorPage()) {
×
106
                throw e;
×
107
            }
108
        } catch (RuntimeException e) {
×
109
            if (containerTweaks.shouldLogUnhandledExceptions()) {
×
110
                // Some containers (such as Tomcat 4) swallow RuntimeExceptions in filters.
111
                servletContext.log("Unhandled exception occurred whilst decorating page", e);
×
112
            }
113
            throw e;
×
114
        } catch (ServletException e) {
×
115
            request.setAttribute(ALREADY_APPLIED_KEY, null);
×
116
            throw e;
×
117
        }
×
118

119
    }
×
120

121
    /**
122
     * Inits the content processor.
123
     *
124
     * @param webAppContext
125
     *            the web app context
126
     *
127
     * @return the content processor
128
     */
129
    protected ContentProcessor initContentProcessor(SiteMeshWebAppContext webAppContext) {
130
        // TODO: Remove heavy coupling on horrible SM2 Factory
131
        Factory factory = Factory.getInstance(new Config(filterConfig));
×
132
        factory.refresh();
×
133
        return new PageParser2ContentProcessor(factory);
×
134
    }
135

136
    /**
137
     * Inits the decorator selector.
138
     *
139
     * @param webAppContext
140
     *            the web app context
141
     *
142
     * @return the decorator selector
143
     */
144
    protected DecoratorSelector initDecoratorSelector(SiteMeshWebAppContext webAppContext) {
145
        // TODO: Remove heavy coupling on horrible SM2 Factory
146
        Factory factory = Factory.getInstance(new Config(filterConfig));
×
147
        factory.refresh();
×
148
        return new DecoratorMapper2DecoratorSelector(factory.getDecoratorMapper());
×
149
    }
150

151
    /**
152
     * Continue in filter-chain, writing all content to buffer and parsing into returned
153
     * {@link com.opensymphony.module.sitemesh.Page} object. If {@link com.opensymphony.module.sitemesh.Page} is not
154
     * parseable, null is returned.
155
     *
156
     * @param contentProcessor
157
     *            the content processor
158
     * @param webAppContext
159
     *            the web app context
160
     * @param request
161
     *            the request
162
     * @param response
163
     *            the response
164
     * @param chain
165
     *            the chain
166
     *
167
     * @return the content
168
     *
169
     * @throws IOException
170
     *             Signals that an I/O exception has occurred.
171
     * @throws ServletException
172
     *             the servlet exception
173
     */
174
    private Content obtainContent(ContentProcessor contentProcessor, SiteMeshWebAppContext webAppContext,
175
            HttpServletRequest request, HttpServletResponse response, FilterChain chain)
176
            throws IOException, ServletException {
177

178
        ContentBufferingResponse contentBufferingResponse = new ContentBufferingResponse(response, contentProcessor,
×
179
                webAppContext);
180
        chain.doFilter(request, contentBufferingResponse);
×
181
        // TODO: check if another servlet or filter put a page object in the request
182
        // Content result = request.getAttribute(PAGE);
183
        // if (result == null) {
184
        // // parse the page
185
        // result = pageResponse.getPage();
186
        // }
187
        webAppContext.setUsingStream(contentBufferingResponse.isUsingStream());
×
188
        return contentBufferingResponse.getContent();
×
189
    }
190

191
    /**
192
     * Filter already applied for request.
193
     *
194
     * @param request
195
     *            the request
196
     *
197
     * @return true, if successful
198
     */
199
    private boolean filterAlreadyAppliedForRequest(HttpServletRequest request) {
200
        if (request.getAttribute(ALREADY_APPLIED_KEY) == Boolean.TRUE) {
×
201
            return true;
×
202
        }
203
        request.setAttribute(ALREADY_APPLIED_KEY, Boolean.TRUE);
×
204
        return false;
×
205
    }
206

207
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc