Java tutorial
/* * Copyright (C) 2007 ETH Zurich * * This file is part of Fosstrak (www.fosstrak.org). * * Fosstrak is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * Fosstrak 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 Fosstrak; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ package org.fosstrak.epcis.repository.capture; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.sql.SQLException; import java.util.Properties; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fosstrak.epcis.repository.InvalidFormatException; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.xml.sax.SAXException; /** * This CaptureOperationsServlet accepts and analyzes HTTP POST requests and * delegates them to the appropriate handler methods in the * CaptureOperationsModule. This servlet also initializes the * CaptureOperationsModule properly and returns a simple information page upon * GET requests. * * @author Marco Steybe */ public class CaptureOperationsServlet extends HttpServlet { private static final long serialVersionUID = -5765052834995535731L; private static final String APP_CONFIG_LOCATION = "appConfigLocation"; private static final String PROP_INSERT_MISSING_VOC = "insertMissingVoc"; private static final String PROP_DB_RESET_ALLOWED = "dbResetAllowed"; private static final String PROP_DB_RESET_SCRIPT = "dbResetScript"; private static final String PROP_EPCIS_SCHEMA_FILE = "epcisSchemaFile"; private static final String PROP_EPCIS_MASTER_DATA_SCHEMA_FILE = "epcisMasterDataSchemaFile"; private static final String PAGE_CAPTURE_INTERFACE = "/WEB-INF/jsp/capture.jsp"; private static final String PAGE_CAPTURE_FORM = "/WEB-INF/jsp/captureForm.jsp"; private static final Log LOG = LogFactory.getLog(CaptureOperationsServlet.class); private CaptureOperationsModule captureOperationsModule; /** * {@inheritDoc} */ public void init() { LOG.debug("Fetching capture operations module from servlet context ..."); CaptureOperationsModule captureOperationsModule = (CaptureOperationsModule) getServletContext() .getAttribute("captureOperationsModule"); if (captureOperationsModule == null) { LOG.debug("Capture operations module not found - initializing manually"); captureOperationsModule = new CaptureOperationsModule(); ServletConfig servletConfig = getServletConfig(); Properties props; if (servletConfig == null) { props = loadApplicationProperties(); } else { props = loadApplicationProperties(servletConfig); } SessionFactory hibernateSessionFactory = initHibernate(); captureOperationsModule.setSessionFactory(hibernateSessionFactory); captureOperationsModule .setInsertMissingVoc(Boolean.parseBoolean(props.getProperty(PROP_INSERT_MISSING_VOC, "true"))); captureOperationsModule .setDbResetAllowed(Boolean.parseBoolean(props.getProperty(PROP_DB_RESET_ALLOWED, "false"))); captureOperationsModule.setDbResetScript(props.getProperty(PROP_DB_RESET_SCRIPT)); captureOperationsModule.setEpcisSchemaFile(props.getProperty(PROP_EPCIS_SCHEMA_FILE)); captureOperationsModule .setEpcisMasterdataSchemaFile(props.getProperty(PROP_EPCIS_MASTER_DATA_SCHEMA_FILE)); } else { LOG.debug("Capture operations module found"); } setCaptureOperationsModule(captureOperationsModule); } /** * Loads the application properties and populates a java.util.Properties * instance. * * @param servletConfig * The ServletConfig used to locate the application property * file. * @return The application properties. */ private Properties loadApplicationProperties(ServletConfig servletConfig) { // read application properties from servlet context ServletContext ctx = servletConfig.getServletContext(); String path = ctx.getRealPath("/"); String appConfigFile = ctx.getInitParameter(APP_CONFIG_LOCATION); Properties properties = new Properties(); try { InputStream is = new FileInputStream(path + appConfigFile); properties.load(is); is.close(); LOG.info("Loaded application properties from " + path + appConfigFile); } catch (IOException e) { LOG.error("Unable to load application properties from " + path + appConfigFile, e); } return properties; } /** * Loads the application properties from classpath and populates a * java.util.Properties instance. * * @param servletConfig * The ServletConfig used to locate the application property * file. * @return The application properties. */ private Properties loadApplicationProperties() { // read application properties from classpath String resource = "/application.properties"; InputStream is = this.getClass().getResourceAsStream(resource); Properties properties = new Properties(); try { properties.load(is); is.close(); LOG.info("Loaded application properties from classpath:" + resource + " (" + this.getClass().getResource(resource) + ")"); } catch (IOException e) { LOG.error("Unable to load application properties from classpath:" + resource + " (" + this.getClass().getResource(resource) + ")", e); } return properties; } /** * Initializes Hibernate. Reads the configuration from hibernate.cfg.xml * located on the classpath (WEB-INF/classes/) * * @return The Hibernate SessionFactory. * @throws ServletException */ private SessionFactory initHibernate() throws HibernateException { LOG.info("Manually initializing Hibernate"); Configuration c = new Configuration(); c.configure(); // from WEB-INF/classes/hibernate.cfg.xml return c.buildSessionFactory(); } /** * Handles HTTP GET requests by dispatching to simple information pages. * * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) * @param req * The servlet request. * @param rsp * The servlet response. * @throws IOException * If an error occurred while writing the response. */ public void doGet(final HttpServletRequest req, final HttpServletResponse rsp) throws ServletException, IOException { RequestDispatcher dispatcher; String dbReset = req.getParameter("dbReset"); if (dbReset != null && dbReset.equalsIgnoreCase("true")) { doDbReset(rsp); } else { String showCaptureForm = req.getParameter("showCaptureForm"); if (showCaptureForm != null && "true".equals(showCaptureForm)) { req.setAttribute("responseMsg", ""); req.setAttribute("detailedMsg", ""); dispatcher = getServletContext().getRequestDispatcher(PAGE_CAPTURE_FORM); } else { dispatcher = getServletContext().getRequestDispatcher(PAGE_CAPTURE_INTERFACE); } dispatcher.forward(req, rsp); } } /** * Implements the EPCIS capture operation. Takes HTTP POST request, extracts * the payload into an XML document, validates the document against the * EPCIS schema, and captures the EPCIS events given in the document. Errors * are caught and returned as simple plaintext messages via HTTP. * * @param req * The HttpServletRequest. * @param rsp * The HttpServletResponse. * @throws IOException * If an error occurred while validating the request or writing * the response. */ public void doPost(final HttpServletRequest req, final HttpServletResponse rsp) throws ServletException, IOException { LOG.info("EPCIS Capture Interface invoked."); InputStream is = null; // check if we have a POST request with form parameters if ("application/x-www-form-urlencoded".equalsIgnoreCase(req.getContentType())) { rsp.setContentType("text/plain"); PrintWriter out = rsp.getWriter(); // check if the 'event' or 'dbReset' form parameter are given String event = req.getParameter("event"); String dbReset = req.getParameter("dbReset"); if (event != null) { LOG.info("Found deprecated 'event=' parameter. Refusing to process request."); String msg = "Starting from version 0.2.2, the EPCIS repository does not accept the EPCISDocument in the HTTP POST form parameter 'event' anymore. Please provide the EPCISDocument as HTTP POST payload instead."; rsp.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); out.println(msg); } else if (dbReset != null && dbReset.equalsIgnoreCase("true")) { doDbReset(rsp); } out.flush(); out.close(); return; } else { is = req.getInputStream(); } // do the capture operation and handle exceptions String responseMsg = ""; String detailedMsg = ""; try { captureOperationsModule.doCapture(is, req.getUserPrincipal()); rsp.setStatus(HttpServletResponse.SC_OK); responseMsg = "EPCIS capture request succeeded."; } catch (SAXException e) { responseMsg = "An error processing the XML document occurred."; detailedMsg = "Unable to parse incoming XML due to error: " + e.getMessage(); LOG.info(detailedMsg); rsp.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (InvalidFormatException e) { responseMsg = "An error parsing the XML contents occurred."; detailedMsg = "Unable to parse incoming EPCISDocument due to error: " + e.getMessage(); LOG.info(detailedMsg); rsp.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (final Exception e) { responseMsg = "An unexpected error occurred."; detailedMsg = "The repository is unable to handle the request due to an internal error."; LOG.error(responseMsg, e); rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } // dispatch the response req.setAttribute("responseMsg", responseMsg); req.setAttribute("detailedMsg", detailedMsg); RequestDispatcher dispatcher; String showCaptureForm = (String) req.getAttribute("showCaptureForm"); if (showCaptureForm != null && "true".equals(showCaptureForm)) { dispatcher = getServletContext().getRequestDispatcher(PAGE_CAPTURE_FORM); } else { dispatcher = getServletContext().getRequestDispatcher(PAGE_CAPTURE_INTERFACE); } dispatcher.forward(req, rsp); } private void doDbReset(final HttpServletResponse rsp) throws IOException { LOG.debug("Found 'dbReset' parameter set to 'true'."); rsp.setContentType("text/plain"); final PrintWriter out = rsp.getWriter(); try { captureOperationsModule.doDbReset(); String msg = "db reset successfull"; LOG.info(msg); rsp.setStatus(HttpServletResponse.SC_OK); out.println(msg); } catch (SQLException e) { String msg = "An error involving the database occurred"; LOG.error(msg, e); rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); out.println(msg); } catch (IOException e) { String msg = "An unexpected error occurred"; LOG.error(msg, e); rsp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); out.println(msg); } catch (UnsupportedOperationException e) { String msg = "'dbReset' operation not allowed!"; LOG.info(msg); rsp.setStatus(HttpServletResponse.SC_FORBIDDEN); out.println(msg); } } public void setCaptureOperationsModule(CaptureOperationsModule captureOperationsModule) { this.captureOperationsModule = captureOperationsModule; } }