diff -r cf85ef18f231 -r e722861558bb src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Mon May 11 19:09:06 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Tue May 12 22:03:00 2020 +0200 @@ -60,12 +60,6 @@ */ private LightPITModule.ELProxy moduleInfo = null; - - @FunctionalInterface - private interface HandlerMethod { - ResponseType apply(HttpServletRequest request, HttpServletResponse response, DataAccessObjects dao) throws IOException, SQLException; - } - /** * Invocation mapping gathered from the {@link RequestMapping} annotations. *

@@ -75,7 +69,7 @@ * The reason for this is the different handling of empty paths in * {@link HttpServletRequest#getPathInfo()}. */ - private final Map> mappings = new HashMap<>(); + private final Map> mappings = new HashMap<>(); /** * Gives implementing modules access to the {@link ModuleManager}. @@ -95,12 +89,10 @@ */ private DataAccessObjects createDataAccessObjects(Connection connection) throws SQLException { final var df = (DatabaseFacade) getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME); - switch (df.getSQLDialect()) { - case Postgres: - return new PGDataAccessObjects(connection); - default: - throw new AssertionError("Non-exhaustive switch - this is a bug."); + if (df.getSQLDialect() == DatabaseFacade.Dialect.Postgres) { + return new PGDataAccessObjects(connection); } + throw new AssertionError("Non-exhaustive if-else - this is a bug."); } private ResponseType invokeMapping(Method method, HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException { @@ -160,9 +152,9 @@ final String requestPath = "/" + mapping.get().requestPath(); - if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()). - putIfAbsent(requestPath, - (req, resp, dao) -> invokeMapping(method, req, resp, dao)) != null) { + if (mappings + .computeIfAbsent(mapping.get().method(), k -> new HashMap<>()) + .putIfAbsent(requestPath, method) != null) { LOG.warn("{} {} has multiple mappings", mapping.get().method(), mapping.get().requestPath() @@ -232,10 +224,10 @@ req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp); } - private Optional findMapping(HttpMethod method, HttpServletRequest req) { - return Optional.ofNullable(mappings.get(method)).map( - (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/")) - ); + private Optional findMapping(HttpMethod method, HttpServletRequest req) { + return Optional.ofNullable(mappings.get(method)) + .map(rm -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/")) + ); } private void forwardAsSpecified(ResponseType type, HttpServletRequest req, HttpServletResponse resp) @@ -277,15 +269,24 @@ final var db = (DatabaseFacade) req.getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME); try (final var connection = db.getDataSource().getConnection()) { final var dao = createDataAccessObjects(connection); - // call the handler, if available, or send an HTTP 404 error - final var mapping = findMapping(method, req); - if (mapping.isPresent()) { - forwardAsSpecified(mapping.get().apply(req, resp, dao), req, resp); - } else { - resp.sendError(HttpServletResponse.SC_NOT_FOUND); + try { + connection.setAutoCommit(false); + // call the handler, if available, or send an HTTP 404 error + final var mapping = findMapping(method, req); + if (mapping.isPresent()) { + forwardAsSpecified(invokeMapping(mapping.get(), req, resp, dao), req, resp); + } else { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } + connection.commit(); + } catch (SQLException ex) { + LOG.warn("Database transaction failed (Code {}): {}", ex.getErrorCode(), ex.getMessage()); + LOG.debug("Details: ", ex); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unhandled Transaction Error - Code:" + ex.getErrorCode()); + connection.rollback(); } } catch (SQLException ex) { - LOG.error("Database exception (Code {}): {}", ex.getErrorCode(), ex.getMessage()); + LOG.error("Severe Database Exception (Code {}): {}", ex.getErrorCode(), ex.getMessage()); LOG.debug("Details: ", ex); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Database Error - Code:" + ex.getErrorCode()); }