src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java

changeset 39
e722861558bb
parent 38
cf85ef18f231
child 40
276ef00a336d
     1.1 --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Mon May 11 19:09:06 2020 +0200
     1.2 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Tue May 12 22:03:00 2020 +0200
     1.3 @@ -60,12 +60,6 @@
     1.4       */
     1.5      private LightPITModule.ELProxy moduleInfo = null;
     1.6  
     1.7 -
     1.8 -    @FunctionalInterface
     1.9 -    private interface HandlerMethod {
    1.10 -        ResponseType apply(HttpServletRequest request, HttpServletResponse response, DataAccessObjects dao) throws IOException, SQLException;
    1.11 -    }
    1.12 -
    1.13      /**
    1.14       * Invocation mapping gathered from the {@link RequestMapping} annotations.
    1.15       * <p>
    1.16 @@ -75,7 +69,7 @@
    1.17       * The reason for this is the different handling of empty paths in
    1.18       * {@link HttpServletRequest#getPathInfo()}.
    1.19       */
    1.20 -    private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>();
    1.21 +    private final Map<HttpMethod, Map<String, Method>> mappings = new HashMap<>();
    1.22  
    1.23      /**
    1.24       * Gives implementing modules access to the {@link ModuleManager}.
    1.25 @@ -95,12 +89,10 @@
    1.26       */
    1.27      private DataAccessObjects createDataAccessObjects(Connection connection) throws SQLException {
    1.28          final var df = (DatabaseFacade) getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME);
    1.29 -        switch (df.getSQLDialect()) {
    1.30 -            case Postgres:
    1.31 -                return new PGDataAccessObjects(connection);
    1.32 -            default:
    1.33 -                throw new AssertionError("Non-exhaustive switch - this is a bug.");
    1.34 +        if (df.getSQLDialect() == DatabaseFacade.Dialect.Postgres) {
    1.35 +            return new PGDataAccessObjects(connection);
    1.36          }
    1.37 +        throw new AssertionError("Non-exhaustive if-else - this is a bug.");
    1.38      }
    1.39  
    1.40      private ResponseType invokeMapping(Method method, HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException {
    1.41 @@ -160,9 +152,9 @@
    1.42  
    1.43                          final String requestPath = "/" + mapping.get().requestPath();
    1.44  
    1.45 -                        if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()).
    1.46 -                                putIfAbsent(requestPath,
    1.47 -                                        (req, resp, dao) -> invokeMapping(method, req, resp, dao)) != null) {
    1.48 +                        if (mappings
    1.49 +                                .computeIfAbsent(mapping.get().method(), k -> new HashMap<>())
    1.50 +                                .putIfAbsent(requestPath, method) != null) {
    1.51                              LOG.warn("{} {} has multiple mappings",
    1.52                                      mapping.get().method(),
    1.53                                      mapping.get().requestPath()
    1.54 @@ -232,10 +224,10 @@
    1.55          req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp);
    1.56      }
    1.57  
    1.58 -    private Optional<HandlerMethod> findMapping(HttpMethod method, HttpServletRequest req) {
    1.59 -        return Optional.ofNullable(mappings.get(method)).map(
    1.60 -                (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/"))
    1.61 -        );
    1.62 +    private Optional<Method> findMapping(HttpMethod method, HttpServletRequest req) {
    1.63 +        return Optional.ofNullable(mappings.get(method))
    1.64 +                .map(rm -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/"))
    1.65 +                );
    1.66      }
    1.67  
    1.68      private void forwardAsSpecified(ResponseType type, HttpServletRequest req, HttpServletResponse resp)
    1.69 @@ -277,15 +269,24 @@
    1.70          final var db = (DatabaseFacade) req.getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME);
    1.71          try (final var connection = db.getDataSource().getConnection()) {
    1.72              final var dao = createDataAccessObjects(connection);
    1.73 -            // call the handler, if available, or send an HTTP 404 error
    1.74 -            final var mapping = findMapping(method, req);
    1.75 -            if (mapping.isPresent()) {
    1.76 -                forwardAsSpecified(mapping.get().apply(req, resp, dao), req, resp);
    1.77 -            } else {
    1.78 -                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
    1.79 +            try {
    1.80 +                connection.setAutoCommit(false);
    1.81 +                // call the handler, if available, or send an HTTP 404 error
    1.82 +                final var mapping = findMapping(method, req);
    1.83 +                if (mapping.isPresent()) {
    1.84 +                    forwardAsSpecified(invokeMapping(mapping.get(), req, resp, dao), req, resp);
    1.85 +                } else {
    1.86 +                    resp.sendError(HttpServletResponse.SC_NOT_FOUND);
    1.87 +                }
    1.88 +                connection.commit();
    1.89 +            } catch (SQLException ex) {
    1.90 +                LOG.warn("Database transaction failed (Code {}): {}", ex.getErrorCode(), ex.getMessage());
    1.91 +                LOG.debug("Details: ", ex);
    1.92 +                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unhandled Transaction Error - Code:" + ex.getErrorCode());
    1.93 +                connection.rollback();
    1.94              }
    1.95          } catch (SQLException ex) {
    1.96 -            LOG.error("Database exception (Code {}): {}", ex.getErrorCode(), ex.getMessage());
    1.97 +            LOG.error("Severe Database Exception (Code {}): {}", ex.getErrorCode(), ex.getMessage());
    1.98              LOG.debug("Details: ", ex);
    1.99              resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Database Error - Code:" + ex.getErrorCode());
   1.100          }

mercurial