<commit_before>package com.psddev.dari.util;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.PageContext;

/**
 * Allows per-thread JSP buffer override.
 *
 * @see Static#setBuffer
 * @see Static#removeBuffer
 */
public class JspBufferFilter extends AbstractFilter {

    private static final ThreadLocal<Integer> BUFFER_OVERRIDE = new ThreadLocal<Integer>();

    @Override
    protected void doInit() {
        JspUtils.wrapDefaultJspFactory(ThreadLocalBufferJspFactory.class);
    }

    @Override
    protected void doDestroy() {
        JspUtils.unwrapDefaultJspFactory(ThreadLocalBufferJspFactory.class);
    }

    private static class ThreadLocalBufferJspFactory extends JspFactoryWrapper {

        @Override
        public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageUrl, boolean needsSession, int buffer, boolean autoflush) {
            Integer override = BUFFER_OVERRIDE.get();

            return super.getPageContext(servlet, request, response, errorPageUrl, needsSession, override != null ? override : buffer, autoflush);
        }
    }

    /** {@link JspBufferFilter} utility methods. */
    public static final class Static {

        private Static() {
        }

        /** Sets the JSP buffer override for this thread. */
        public static void setBufferOverride(int buffer) {
            BUFFER_OVERRIDE.set(buffer);
        }

        /** Removes the JSP buffer override for this thread. */
        public static void removeBufferOverride() {
            BUFFER_OVERRIDE.remove();
        }
    }
}<commit_msg>Changes JspBufferFilter so that restoring the previous buffer size isn't so error-prone.<commit_after>package com.psddev.dari.util;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.PageContext;

/**
 * Allows per-thread JSP buffer override.
 *
 * @see Static#overrideBuffer
 * @see Static#restoreBuffer
 */
public class JspBufferFilter extends AbstractFilter {

    private static final ThreadLocalStack<Integer> BUFFER_OVERRIDE = new ThreadLocalStack<Integer>();

    @Override
    protected void doInit() {
        JspUtils.wrapDefaultJspFactory(ThreadLocalBufferJspFactory.class);
    }

    @Override
    protected void doDestroy() {
        JspUtils.unwrapDefaultJspFactory(ThreadLocalBufferJspFactory.class);
    }

    private static class ThreadLocalBufferJspFactory extends JspFactoryWrapper {

        @Override
        public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageUrl, boolean needsSession, int buffer, boolean autoflush) {
            Integer override = BUFFER_OVERRIDE.get();

            return super.getPageContext(servlet, request, response, errorPageUrl, needsSession, override != null ? override : buffer, autoflush);
        }
    }

    /** {@link JspBufferFilter} utility methods. */
    public static final class Static {

        private Static() {
        }

        /** Overrides the current JSP buffer value for this thread. */
        public static void overrideBuffer(int buffer) {
            BUFFER_OVERRIDE.push(buffer);
        }

        /** Restores the last JSP buffer value for this thread. */
        public static Integer restoreBuffer() {
            return BUFFER_OVERRIDE.pop();
        }

        /** @deprecated Use {@link #pushBufferOverride} instead. */
        @Deprecated
        public static void setBufferOverride(int buffer) {
            BUFFER_OVERRIDE.set(buffer);
        }

        /** @deprecated Use {@link #popBufferOverride} instead. */
        @Deprecated
        public static void removeBufferOverride() {
            BUFFER_OVERRIDE.remove();
        }
    }
}
{'fraction_non_alphanumeric': 0.08352728213085078, 'fraction_numerical': 0.0, 'mean_word_length': 3.0887949260042284, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4891182', 'n_tokens_mistral': 1030, 'n_tokens_neox': 980, 'n_words': 269}