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

org.s1.web.pages.PagesServlet Maven / Gradle / Ivy

There is a newer version: 0.1.3
Show newest version
package org.s1.web.pages;

import groovy.text.GStringTemplateEngine;
import groovy.text.SimpleTemplateEngine;
import groovy.text.Template;
import org.s1.web.services.WebOperationInput;
import org.s1.web.session.RequestScope;
import org.s1.web.session.SessionScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Serving GSP pages.
 * 

 * <servlet>
 *  <servlet-name>pages</servlet-name>
 *  <servlet-class>org.s1.web.pages.PagesServlet</servlet-class>
 *  <load-on-startup>1</load-on-startup>
 * </servlet>
 * <servlet-mapping>
 *  <servlet-name>pages</servlet-name>
 *  <url-pattern>*.gsp</url-pattern>
 * </servlet-mapping>
 * 
*
* Your pages should be written with Groovy templates (http://groovy.codehaus.org/Groovy+Templates). *
* Notice: ${...} code style is disabled (it may conflicts with some Javascript libraries). * * @author Grigory Pykhov */ public class PagesServlet extends HttpServlet { private static final Logger LOG = LoggerFactory.getLogger(PagesServlet.class); private static Map templateCache = new ConcurrentHashMap(); /** * Layout content variable */ private static final String LAYOUT_CONTENT_VARIABLE = "layout_content"; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { process(req, resp); } /** * Process request * * @param req Request * @param resp Response * @throws ServletException ServletException * @throws IOException IOException */ protected void process(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = null; try { id = SessionScope.retrieveSessionIdFromRequest(req, resp); SessionScope.start(id); RequestScope.start(new RequestScope.Context(req, resp)); String path = req.getServletContext().getRealPath("/"); if (path.startsWith("WEB-INF")) { resp.setStatus(403); return; } String page = req.getRequestURI().substring(req.getContextPath().length()); resp.setContentType("text/html"); resp.setCharacterEncoding("UTF-8"); String res = ""; res = render("", path, page, new WebOperationInput(req, resp), new HashMap(), req, resp); resp.getOutputStream().write(res.getBytes(Charset.forName("UTF-8"))); } finally { RequestScope.finish(); SessionScope.finish(id); } } private static class TemplateCacheRecord { private Template template; private long updateTime; private long size; public TemplateCacheRecord(Template template, long updateTime, long size) { this.template = template; this.updateTime = updateTime; this.size = size; } } /** * Renders page * * @param currentFileDirectoryPath Current directory path * @param webappDirectoryPath Webapp root path * @param pagePath Requested page path * @param params Request params * @param pageArguments Included page arguments (or for Layout page) * @param req Request * @param resp Response * @return Rendered page */ protected static String render(final String currentFileDirectoryPath, final String webappDirectoryPath, final String pagePath, final WebOperationInput params, final Map pageArguments, final HttpServletRequest req, final HttpServletResponse resp) { String pageRealPath = ""; if (pagePath.startsWith("/")) { //absolute pageRealPath = webappDirectoryPath + "/" + pagePath; } else { //relative pageRealPath = currentFileDirectoryPath + "/" + pagePath; } pageRealPath = pageRealPath.replaceAll("\\\\", "/").replaceAll("/+", "/").replace("/", File.separator); try { final String currentPath = pageRealPath.substring(0, pageRealPath.lastIndexOf(File.separator)); //LOG.debug("Rendering page: " + page); Path p1 = FileSystems.getDefault().getPath(pageRealPath); if (templateCache.containsKey(pageRealPath)) { if (templateCache.get(pageRealPath).updateTime != Files.getLastModifiedTime(p1).toMillis() || templateCache.get(pageRealPath).size != Files.size(p1)) { templateCache.remove(pageRealPath); } } if (!templateCache.containsKey(pageRealPath)) { //GStringTemplateEngine engine = new GStringTemplateEngine(); SimpleTemplateEngine engine = new SimpleTemplateEngine(); String temp = new String(Files.readAllBytes(p1), StandardCharsets.UTF_8); temp = temp.replace("$", "\\$"); Template template = engine.createTemplate( temp); templateCache.put(pageRealPath, new TemplateCacheRecord(template, Files.getLastModifiedTime(p1).toMillis(), Files.size(p1))); } Template template = templateCache.get(pageRealPath).template; if (template == null) { resp.setStatus(404); LOG.warn("Page not found: " + pageRealPath); return ""; } Map ctx = new HashMap(); PageContext pageContext = new PageContext(req, resp, params, currentPath, webappDirectoryPath); ctx.put("page", pageContext); ctx.put("args", pageArguments); String text = template.make(ctx).toString(); if (pageContext.layoutPath != null && !pageContext.layoutPath.isEmpty()) { pageContext.layoutArgs.put(LAYOUT_CONTENT_VARIABLE, text); text = render(currentPath, webappDirectoryPath, pageContext.layoutPath, params, pageContext.layoutArgs, req, resp); } return text; } catch (Throwable e) { LOG.warn("Layout page: " + pageRealPath + " error " + e.getClass().getName() + ": " + e.getMessage(), e); return ""; } } /** * Page context */ public static class PageContext { private HttpServletRequest request; private HttpServletResponse response; private WebOperationInput params; private String currentPath; private String directory; /** * @param request Request * @param response Response * @param params Request params * @param currentPath Current directory path * @param directory Webapp root directory */ public PageContext(HttpServletRequest request, HttpServletResponse response, WebOperationInput params, String currentPath, String directory) { this.request = request; this.response = response; this.params = params; this.currentPath = currentPath; this.directory = directory; } private String layoutPath; private Map layoutArgs = new HashMap(); /** * Do layout * * @param path Path to layout page */ public void layout(String path) { this.layoutPath = path; } /** * Do layout * * @param path Path to layout page * @param args Layout page arguments */ public void layout(String path, Map args) { this.layoutPath = path; this.layoutArgs = args; } /** * Includes page * * @param pagePath Path to page * @param args Page arguments * @return Rendered page */ public String include(String pagePath, Map args) { String t = render(currentPath, directory, pagePath, params, args, request, response); return t; } /** * @return Request */ public HttpServletRequest getRequest() { return request; } /** * @return Response */ public HttpServletResponse getResponse() { return response; } /** * @return Params */ public WebOperationInput getParams() { return params; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy