• 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/module/sitemesh/filter/PageResponseWrapper.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2011-2026 Hazendaz
4
 */
5
/* This software is published under the terms of the OpenSymphony Software
6
 * License version 1.1, of which a copy has been included with this
7
 * distribution in the LICENSE.txt file. */
8
package com.opensymphony.module.sitemesh.filter;
9

10
import com.opensymphony.module.sitemesh.Page;
11
import com.opensymphony.module.sitemesh.PageParserSelector;
12
import com.opensymphony.module.sitemesh.SitemeshBuffer;
13

14
import jakarta.servlet.ServletOutputStream;
15
import jakarta.servlet.http.HttpServletResponse;
16
import jakarta.servlet.http.HttpServletResponseWrapper;
17

18
import java.io.IOException;
19
import java.io.PrintWriter;
20

21
/**
22
 * Implementation of HttpServletResponseWrapper that captures page data instead of sending to the writer.
23
 * <p>
24
 * Should be used in filter-chains or when forwarding/including pages using a RequestDispatcher.
25
 *
26
 * @author <a href="mailto:joe@truemesh.com">Joe Walnes</a>
27
 * @author <a href="mailto:scott@atlassian.com">Scott Farquhar</a>
28
 */
29
public class PageResponseWrapper extends HttpServletResponseWrapper {
30

31
    /** The routable print writer. */
32
    private final RoutablePrintWriter routablePrintWriter;
33

34
    /** The routable servlet output stream. */
35
    private final RoutableServletOutputStream routableServletOutputStream;
36

37
    /** The parser selector. */
38
    private final PageParserSelector parserSelector;
39

40
    /** The buffer. */
41
    private Buffer buffer;
42

43
    /** The aborted. */
44
    private boolean aborted;
45

46
    /** The parseable page. */
47
    private boolean parseablePage;
48

49
    /**
50
     * Instantiates a new page response wrapper.
51
     *
52
     * @param response
53
     *            the response
54
     * @param parserSelector
55
     *            the parser selector
56
     */
57
    public PageResponseWrapper(final HttpServletResponse response, PageParserSelector parserSelector) {
58
        super(response);
×
59
        this.parserSelector = parserSelector;
×
60

61
        routablePrintWriter = new RoutablePrintWriter(response::getWriter);
×
62
        routableServletOutputStream = new RoutableServletOutputStream(response::getOutputStream);
×
63

64
    }
×
65

66
    /**
67
     * Set the content-type of the request and store it so it can be passed to the
68
     * {@link com.opensymphony.module.sitemesh.PageParser}.
69
     */
70
    @Override
71
    public void setContentType(String type) {
72
        super.setContentType(type);
×
73

74
        if (type != null) {
×
75
            HttpContentType httpContentType = new HttpContentType(type);
×
76

77
            if (parserSelector.shouldParsePage(httpContentType.getType())) {
×
78
                activateSiteMesh(httpContentType.getType(), httpContentType.getEncoding());
×
79
            } else {
80
                deactivateSiteMesh();
×
81
            }
82
        }
83

84
    }
×
85

86
    /**
87
     * Activate site mesh.
88
     *
89
     * @param contentType
90
     *            the content type
91
     * @param encoding
92
     *            the encoding
93
     */
94
    public void activateSiteMesh(String contentType, String encoding) {
95
        if (parseablePage) {
×
96
            return; // already activated
×
97
        }
98
        buffer = new Buffer(parserSelector.getPageParser(contentType), encoding);
×
99
        routablePrintWriter.updateDestination(buffer::getWriter);
×
100
        routableServletOutputStream.updateDestination(buffer::getOutputStream);
×
101
        parseablePage = true;
×
102
    }
×
103

104
    /**
105
     * Deactivate site mesh.
106
     */
107
    private void deactivateSiteMesh() {
108
        parseablePage = false;
×
109
        buffer = null;
×
110
        routablePrintWriter.updateDestination(() -> getResponse().getWriter());
×
111
        routableServletOutputStream.updateDestination(() -> getResponse().getOutputStream());
×
112
    }
×
113

114
    /**
115
     * Prevent content-length being set if page is parseable.
116
     */
117
    @Override
118
    public void setContentLength(int contentLength) {
119
        if (!parseablePage) {
×
120
            super.setContentLength(contentLength);
×
121
        }
122
    }
×
123

124
    /**
125
     * Prevent buffer from being flushed if this is a page being parsed.
126
     */
127
    @Override
128
    public void flushBuffer() throws IOException {
129
        if (!parseablePage) {
×
130
            super.flushBuffer();
×
131
        }
132
    }
×
133

134
    /**
135
     * Prevent content-length being set if page is parseable.
136
     */
137
    @Override
138
    public void setHeader(String name, String value) {
139
        if (name.equalsIgnoreCase("content-type")) { // ensure ContentType is always set through setContentType()
×
140
            setContentType(value);
×
141
        } else if (!parseablePage || !name.equalsIgnoreCase("content-length")) {
×
142
            super.setHeader(name, value);
×
143
        }
144
    }
×
145

146
    /**
147
     * Prevent content-length being set if page is parseable.
148
     */
149
    @Override
150
    public void addHeader(String name, String value) {
151
        if (name.equalsIgnoreCase("content-type")) { // ensure ContentType is always set through setContentType()
×
152
            setContentType(value);
×
153
        } else if (!parseablePage || !name.equalsIgnoreCase("content-length")) {
×
154
            super.addHeader(name, value);
×
155
        }
156
    }
×
157

158
    /**
159
     * If 'not modified' (304) HTTP status is being sent - then abort parsing, as there shouldn't be any body
160
     */
161
    @Override
162
    public void setStatus(int sc) {
163
        if (sc == HttpServletResponse.SC_NOT_MODIFIED) {
×
164
            aborted = true;
×
165
            // route any content back to the original writer. There shouldn't be any content, but just to be safe
166
            deactivateSiteMesh();
×
167
        }
168
        super.setStatus(sc);
×
169
    }
×
170

171
    @Override
172
    public ServletOutputStream getOutputStream() {
173
        return routableServletOutputStream;
×
174
    }
175

176
    @Override
177
    public PrintWriter getWriter() {
178
        return routablePrintWriter;
×
179
    }
180

181
    /**
182
     * Gets the page.
183
     *
184
     * @return the page
185
     *
186
     * @throws IOException
187
     *             Signals that an I/O exception has occurred.
188
     */
189
    public Page getPage() throws IOException {
190
        if (aborted || !parseablePage) {
×
191
            return null;
×
192
        }
193
        return buffer.parse();
×
194
    }
195

196
    @Override
197
    public void sendError(int sc) throws IOException {
198
        aborted = true;
×
199
        super.sendError(sc);
×
200
    }
×
201

202
    @Override
203
    public void sendError(int sc, String msg) throws IOException {
204
        aborted = true;
×
205
        super.sendError(sc, msg);
×
206
    }
×
207

208
    @Override
209
    public void sendRedirect(String location) throws IOException {
210
        aborted = true;
×
211
        super.sendRedirect(location);
×
212
    }
×
213

214
    /**
215
     * Checks if is using stream.
216
     *
217
     * @return true, if is using stream
218
     */
219
    public boolean isUsingStream() {
220
        return buffer != null && buffer.isUsingStream();
×
221
    }
222

223
    /**
224
     * Gets the contents.
225
     *
226
     * @return the contents
227
     *
228
     * @throws IOException
229
     *             Signals that an I/O exception has occurred.
230
     */
231
    public SitemeshBuffer getContents() throws IOException {
232
        if (aborted || !parseablePage) {
×
233
            return null;
×
234
        }
235
        return buffer.getContents();
×
236
    }
237

238
}
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