001/* 002 * Shredzone Commons 003 * 004 * Copyright (C) 2012 Richard "Shred" Körber 005 * http://commons.shredzone.org 006 * 007 * This program is free software: you can redistribute it and/or modify 008 * it under the terms of the GNU Library General Public License as 009 * published by the Free Software Foundation, either version 3 of the 010 * License, or (at your option) any later version. 011 * 012 * This program is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU Library General Public License 018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 019 */ 020 021package org.shredzone.commons.view.servlet; 022 023import java.util.concurrent.atomic.AtomicReference; 024 025import javax.annotation.Nonnull; 026import javax.annotation.ParametersAreNonnullByDefault; 027import javax.servlet.ServletConfig; 028import javax.servlet.ServletException; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031 032import org.shredzone.commons.view.ViewService; 033import org.shredzone.commons.view.exception.ViewException; 034import org.slf4j.LoggerFactory; 035import org.springframework.web.servlet.FrameworkServlet; 036 037/** 038 * Main servlet for handling all kind of view requests. 039 * 040 * @author Richard "Shred" Körber 041 */ 042@ParametersAreNonnullByDefault 043public class ViewServlet extends FrameworkServlet { 044 private static final long serialVersionUID = 6193053466721043404L; 045 046 private final AtomicReference<ViewService> viewService = new AtomicReference<>(); 047 048 @Override 049 public void init(ServletConfig config) throws ServletException { 050 super.init(config); 051 getServletContext().setAttribute("jspPath", getJspPath(config)); 052 } 053 054 @Override 055 protected void doService(HttpServletRequest req, HttpServletResponse resp) throws Exception { 056 try { 057 getViewService().handleRequest(req, resp); 058 } catch (ViewException ex) { 059 LoggerFactory.getLogger(getClass()).error("Failed to handle request", ex); 060 if (!resp.isCommitted()) { 061 resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage()); //NOSONAR 062 } 063 } 064 } 065 066 /** 067 * Returns the {@link ViewService} singleton. 068 */ 069 private @Nonnull ViewService getViewService() { 070 ViewService result = viewService.get(); 071 if (result == null) { 072 result = getWebApplicationContext().getBean(ViewService.class); 073 viewService.compareAndSet(null, result); 074 } 075 return result; 076 } 077 078 /** 079 * Gets the JSP path from the servlet configuration. The default implementation 080 * fetches the value from the servlet's "jspPath" init parameter. Extending classes 081 * may override this method to fetch the configuration from somewhere else. 082 * 083 * @param config 084 * {@link ServletConfig} 085 * @return JSP path, must end with a trailing '/' 086 */ 087 protected @Nonnull String getJspPath(ServletConfig config) { 088 String jspPath = "/"; 089 String path = config.getInitParameter("jspPath"); 090 if (path != null) { 091 if (!path.endsWith("/")) { 092 path += "/"; 093 } 094 jspPath = path; 095 } 096 return jspPath; 097 } 098 099}