All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.semanticcms.core.servlet.PageContext Maven / Gradle / Ivy

There is a newer version: 1.20.0
Show newest version
/*
 * semanticcms-core-servlet - Java API for modeling web page content and relationships in a Servlet environment.
 * Copyright (C) 2016, 2017, 2018, 2019, 2020, 2021, 2022  AO Industries, Inc.
 *     [email protected]
 *     7262 Bull Pen Cir
 *     Mobile, AL 36695
 *
 * This file is part of semanticcms-core-servlet.
 *
 * semanticcms-core-servlet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * semanticcms-core-servlet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with semanticcms-core-servlet.  If not, see .
 */

package com.semanticcms.core.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.Callable;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.SkipPageException;

/**
 * 

* HttpServletRequest, HttpServletResponse, and the response PrintWriter are frequently accessed * while also frequently updated by elements for capture. It is tedious to pass these objects around * all over. Also, with the lambda scoping in Java 8, it is easy to use the wrong object from a * different scope (and possibly capturing context). *

*

* Each context is intended to be established and used within a single servlet implementation. * Do not assume correct management of PageContext between different pages, servlets, or files. * If in doubt, skip this shortcut and pass explicit object references around. *

* * @see PageContextWriter */ public final class PageContext { /** Make no instances, all is done through thread locals. */ private PageContext() { throw new AssertionError(); } static final ThreadLocal servletContext = new ThreadLocal<>(); static final ThreadLocal request = new ThreadLocal<>(); static final ThreadLocal response = new ThreadLocal<>(); static final ThreadLocal out = new ThreadLocal<>(); @FunctionalInterface public static interface PageContextRunnable { void run() throws ServletException, IOException; } public static void newPageContext( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextRunnable target ) throws ServletException, IOException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } target.run(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } @FunctionalInterface public static interface PageContextCallable extends Callable { @Override V call() throws ServletException, IOException; } public static V newPageContext( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextCallable target ) throws ServletException, IOException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } return target.call(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } @FunctionalInterface public static interface PageContextRunnableSkip { void run() throws ServletException, IOException, SkipPageException; } /** * Establishes a new page context. * This usually does not need to be done directly as creating a page will * establish the starting page context. */ public static void newPageContextSkip( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextRunnableSkip target ) throws ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } target.run(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } @FunctionalInterface public static interface PageContextCallableSkip extends Callable { @Override V call() throws ServletException, IOException, SkipPageException; } /** * Establishes a new page context. * This usually does not need to be done directly as creating a page will * establish the starting page context. */ public static V newPageContextSkip( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextCallableSkip target ) throws ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } return target.call(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } /** * @param An arbitrary exception type that may be thrown */ @FunctionalInterface public static interface PageContextRunnableSkipE { void run() throws Ex, ServletException, IOException, SkipPageException; } /** * @param An arbitrary exception type that may be thrown */ public static void newPageContextSkipE( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextRunnableSkipE target ) throws Ex, ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } target.run(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } /** * @param An arbitrary exception type that may be thrown */ @FunctionalInterface // TODO: Ex extends Throwable public static interface PageContextCallableSkipE extends Callable { @Override V call() throws Ex, ServletException, IOException, SkipPageException; } /** * @param An arbitrary exception type that may be thrown */ // TODO: Ex extends Throwable public static V newPageContextSkipE( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextCallableSkipE target ) throws Ex, ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } return target.call(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } @FunctionalInterface public static interface PageContextRunnableSkipEE { void run() throws Ex1, Ex2, ServletException, IOException, SkipPageException; } public static void newPageContextSkipEE( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextRunnableSkipEE target ) throws Ex1, Ex2, ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } target.run(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } @FunctionalInterface public static interface PageContextCallableSkipEE extends Callable { @Override V call() throws Ex1, Ex2, ServletException, IOException, SkipPageException; } public static V newPageContextSkipEE( ServletContext newServletContext, HttpServletRequest newRequest, HttpServletResponse newResponse, PageContextCallableSkipEE target ) throws Ex1, Ex2, ServletException, IOException, SkipPageException { final ServletContext oldServletContext = servletContext.get(); final HttpServletRequest oldRequest = request.get(); final HttpServletResponse oldResponse = response.get(); final PrintWriter oldOut = out.get(); PrintWriter newOut = null; try { if (newServletContext != oldServletContext) { servletContext.set(newServletContext); } if (newRequest != oldRequest) { request.set(newRequest); } if (newResponse != oldResponse) { response.set(newResponse); out.remove(); } else { newOut = oldOut; } return target.call(); } finally { if (newServletContext != oldServletContext) { if (oldServletContext == null) { servletContext.remove(); } else { servletContext.set(oldServletContext); } } if (newRequest != oldRequest) { if (oldRequest == null) { request.remove(); } else { request.set(oldRequest); } } if (newResponse != oldResponse) { if (oldResponse == null) { response.remove(); } else { response.set(oldResponse); } } if (newOut != oldOut) { if (oldOut == null) { out.remove(); } else { out.set(oldOut); } } } } /** * Gets the current servlet context. * * @throws IllegalStateException if no context set */ public static ServletContext getServletContext() throws IllegalStateException { ServletContext s = servletContext.get(); if (s == null) { throw new IllegalStateException("No page context"); } return s; } /** * Gets the current request. * * @throws IllegalStateException if no context set */ public static HttpServletRequest getRequest() throws IllegalStateException { HttpServletRequest r = request.get(); if (r == null) { throw new IllegalStateException("No page context"); } return r; } /** * Gets the current response. * * @throws IllegalStateException if no context set */ public static HttpServletResponse getResponse() throws IllegalStateException { HttpServletResponse r = response.get(); if (r == null) { throw new IllegalStateException("No page context"); } return r; } /** * Gets the current response writer. * * @throws IllegalStateException if no context set */ public static PrintWriter getOut() throws IllegalStateException, IOException { PrintWriter o = out.get(); if (o == null) { o = getResponse().getWriter(); out.set(o); } return o; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy