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

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

/*
 * semanticcms-core-servlet - Java API for modeling web page content and relationships in a Servlet environment.
 * Copyright (C) 2013, 2014, 2015, 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 static com.semanticcms.core.servlet.Resources.PACKAGE_RESOURCES;

import com.aoapps.encoding.Doctype;
import com.aoapps.encoding.Serialization;
import com.aoapps.encoding.taglib.EncodingBufferedTag;
import com.aoapps.io.buffer.BufferWriter;
import com.aoapps.io.buffer.EmptyResult;
import com.aoapps.lang.LocalizedIllegalStateException;
import com.aoapps.servlet.http.NullHttpServletResponseWrapper;
import com.semanticcms.core.model.PageRef;
import com.semanticcms.core.servlet.impl.PageImpl;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.jsp.SkipPageException;
import org.apache.commons.lang3.NotImplementedException;
import org.joda.time.ReadableDateTime;

public class Page {

  private final ServletContext servletContext;
  private final HttpServletRequest request;
  private final HttpServletResponse response;

  private PageRef pageRef;

  private ReadableDateTime dateCreated;
  private ReadableDateTime datePublished;
  private ReadableDateTime dateModified;
  private ReadableDateTime dateReviewed;

  private Serialization serialization;
  private Doctype doctype;
  private Boolean autonli;
  private Boolean indent;

  private final String title;

  private String shortTitle;
  private String description;
  private String keywords;
  private Boolean allowRobots;
  private Boolean toc;
  private int tocLevels = com.semanticcms.core.model.Page.DEFAULT_TOC_LEVELS;
  private boolean allowParentMismatch;
  private boolean allowChildMismatch;
  private Map properties;

  public Page(
      ServletContext servletContext,
      HttpServletRequest request,
      HttpServletResponse response,
      String title
  ) {
    this.servletContext = servletContext;
    this.request = request;
    this.response = response;
    this.title = title;
  }

  /**
   * Creates a new page in the current page context.
   *
   * @see  PageContext
   */
  public Page(String title) {
    this(
        PageContext.getServletContext(),
        PageContext.getRequest(),
        PageContext.getResponse(),
        title
    );
  }

  public Page pageRef(PageRef pageRef) {
    this.pageRef = pageRef;
    return this;
  }

  public Page dateCreated(ReadableDateTime dateCreated) {
    this.dateCreated = dateCreated;
    return this;
  }

  public Page datePublished(ReadableDateTime datePublished) {
    this.datePublished = datePublished;
    return this;
  }

  public Page dateModified(ReadableDateTime dateModified) {
    this.dateModified = dateModified;
    return this;
  }

  public Page dateReviewed(ReadableDateTime dateReviewed) {
    this.dateReviewed = dateReviewed;
    return this;
  }

  public Page serialization(Serialization serialization) {
    this.serialization = serialization;
    return this;
  }

  public Page doctype(Doctype doctype) {
    this.doctype = doctype;
    return this;
  }

  public Page autonli(Boolean autonli) {
    this.autonli = autonli;
    return this;
  }

  public Page indent(Boolean indent) {
    this.indent = indent;
    return this;
  }

  public Page shortTitle(String shortTitle) {
    this.shortTitle = shortTitle;
    return this;
  }

  public Page description(String description) {
    this.description = description;
    return this;
  }

  public Page keywords(String keywords) {
    this.keywords = keywords;
    return this;
  }

  public Page allowRobots(Boolean allowRobots) {
    this.allowRobots = allowRobots;
    return this;
  }

  public Page toc(Boolean toc) {
    this.toc = toc;
    return this;
  }

  public Page tocLevels(int tocLevels) {
    this.tocLevels = tocLevels;
    return this;
  }

  public Page allowParentMismatch(boolean allowParentMismatch) {
    this.allowParentMismatch = allowParentMismatch;
    return this;
  }

  public Page allowChildMismatch(boolean allowChildMismatch) {
    this.allowChildMismatch = allowChildMismatch;
    return this;
  }

  /**
   * Adds a property to the page.
   *
   * @throws  IllegalStateException  if the property with the given name has already been set
   */
  public Page property(String name, Object value) throws IllegalStateException {
    if (properties == null) {
      properties = new LinkedHashMap<>();
    } else if (properties.containsKey(name)) {
      throw new LocalizedIllegalStateException(
          PACKAGE_RESOURCES,
          "error.duplicatePageProperty",
          name
      );
    }
    properties.put(name, value);
    return this;
  }

  @FunctionalInterface
  public static interface Body {
    void doBody(HttpServletRequest req, HttpServletResponse resp, com.semanticcms.core.model.Page page) throws ServletException, IOException, SkipPageException;
  }

  /**
   * 

* Sets request attribute "page" to the current page, and restores the previous "page" * attribute once completed. *

*

* Also establishes a new {@link PageContext}. *

* * @see PageContext * @see CurrentPage#REQUEST_ATTRIBUTE */ public void invoke(final Body body) throws ServletException, IOException, SkipPageException { PageRef pr = pageRef; if (pr == null) { pr = PageRefResolver.getCurrentPageRef(servletContext, request); } PageImpl.doPageImpl( servletContext, request, response, pr, dateCreated, datePublished, dateModified, dateReviewed, serialization, doctype, autonli, indent, title, shortTitle, description, keywords, allowRobots, toc, tocLevels, allowParentMismatch, allowChildMismatch, properties, body == null ? null : (discard, page) -> { if (discard) { final HttpServletResponse newResponse = new NullHttpServletResponseWrapper(response); // Set PageContext PageContext.newPageContextSkip( servletContext, request, newResponse, () -> body.doBody(request, newResponse, page) ); return EmptyResult.getInstance(); } else { BufferWriter capturedOut = EncodingBufferedTag.newBufferWriter(request); try { try (PrintWriter capturedPW = new PrintWriter(capturedOut)) { final HttpServletResponse newResponse = new HttpServletResponseWrapper(response) { @Override public PrintWriter getWriter() throws IOException { return capturedPW; } @Override public ServletOutputStream getOutputStream() { throw new NotImplementedException("getOutputStream not expected"); } }; // Set PageContext PageContext.newPageContextSkip( servletContext, request, newResponse, () -> body.doBody(request, newResponse, page) ); if (capturedPW.checkError()) { throw new IOException("Error on capturing PrintWriter"); } } } finally { capturedOut.close(); } return capturedOut.getResult(); } } ); } /** * @see #invoke(com.semanticcms.core.servlet.Page.Body) */ public void invoke() throws ServletException, IOException, SkipPageException { invoke((Body) null); } @FunctionalInterface public static interface PageContextBody { void doBody(com.semanticcms.core.model.Page page) throws ServletException, IOException, SkipPageException; } /** * @see #invoke(com.semanticcms.core.servlet.Page.Body) */ public void invoke(final PageContextBody body) throws ServletException, IOException, SkipPageException { invoke( body == null ? null : (HttpServletRequest req, HttpServletResponse resp, com.semanticcms.core.model.Page page) -> body.doBody(page) ); } @FunctionalInterface public static interface PageContextNoPageBody { void doBody() throws ServletException, IOException, SkipPageException; } /** * @see #invoke(com.semanticcms.core.servlet.Page.Body) */ public void invoke(final PageContextNoPageBody body) throws ServletException, IOException, SkipPageException { invoke( body == null ? null : (HttpServletRequest req, HttpServletResponse resp, com.semanticcms.core.model.Page page) -> body.doBody() ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy