cleanup and simplification of database access layer

Sat, 09 May 2020 17:01:29 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 09 May 2020 17:01:29 +0200
changeset 34
824d4042c857
parent 33
fd8c40ff78c3
child 35
4fa33bfa8fb9

cleanup and simplification of database access layer

src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/Constants.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/DatabaseFacade.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/Functions.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/HttpMethod.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/LightPITModule.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/Menu.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/MenuEntry.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/ModuleManager.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/RequestMapping.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/ResourceKey.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/ResponseType.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/AbstractDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/CoreDAOFactory.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/GenericDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/ModuleDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/UserDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGModuleDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/entities/Module.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/ErrorModule.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/HomeModule.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/LanguageModule.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/ModuleManagerModule.java file | annotate | diff | comparison | revisions
src/main/java/de/uapcore/lightpit/modules/VersionsModule.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Sat May 09 15:19:21 2020 +0200
     1.2 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java	Sat May 09 17:01:29 2020 +0200
     1.3 @@ -1,8 +1,8 @@
     1.4  /*
     1.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     1.6 - * 
     1.7 + *
     1.8   * Copyright 2018 Mike Becker. All rights reserved.
     1.9 - * 
    1.10 + *
    1.11   * Redistribution and use in source and binary forms, with or without
    1.12   * modification, are permitted provided that the following conditions are met:
    1.13   *
    1.14 @@ -24,7 +24,7 @@
    1.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    1.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    1.17   * POSSIBILITY OF SUCH DAMAGE.
    1.18 - * 
    1.19 + *
    1.20   */
    1.21  package de.uapcore.lightpit;
    1.22  
    1.23 @@ -46,9 +46,9 @@
    1.24   * the necessary functionality for {@link LightPITModule}s.
    1.25   */
    1.26  public abstract class AbstractLightPITServlet extends HttpServlet {
    1.27 -    
    1.28 +
    1.29      private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class);
    1.30 -    
    1.31 +
    1.32      private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full");
    1.33  
    1.34      /**
    1.35 @@ -66,14 +66,14 @@
    1.36      private interface HandlerMethod {
    1.37          ResponseType apply(HttpServletRequest t, HttpServletResponse u) throws IOException;
    1.38      }
    1.39 -    
    1.40 +
    1.41      /**
    1.42       * Invocation mapping gathered from the {@link RequestMapping} annotations.
    1.43 -     * 
    1.44 +     * <p>
    1.45       * Paths in this map must always start with a leading slash, although
    1.46       * the specification in the annotation must not start with a leading slash.
    1.47 -     * 
    1.48 -     * The reason for this is the different handling of empty paths in 
    1.49 +     * <p>
    1.50 +     * The reason for this is the different handling of empty paths in
    1.51       * {@link HttpServletRequest#getPathInfo()}.
    1.52       */
    1.53      private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>();
    1.54 @@ -87,6 +87,11 @@
    1.55          return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME);
    1.56      }
    1.57  
    1.58 +    /**
    1.59 +     * Returns the annotated module information.
    1.60 +     *
    1.61 +     * @return the module annotation
    1.62 +     */
    1.63      public final LightPITModule getModuleInfo() {
    1.64          return moduleInfo;
    1.65      }
    1.66 @@ -152,8 +157,8 @@
    1.67                      if (params.length == 2
    1.68                              && HttpServletRequest.class.isAssignableFrom(params[0])
    1.69                              && HttpServletResponse.class.isAssignableFrom(params[1])) {
    1.70 -                        
    1.71 -                        final String requestPath = "/"+mapping.get().requestPath();
    1.72 +
    1.73 +                        final String requestPath = "/" + mapping.get().requestPath();
    1.74  
    1.75                          if (mappings.computeIfAbsent(mapping.get().method(), k -> new HashMap<>()).
    1.76                                  putIfAbsent(requestPath,
    1.77 @@ -187,73 +192,72 @@
    1.78          mappings.clear();
    1.79          LOG.trace("{} destroyed", getServletName());
    1.80      }
    1.81 -    
    1.82 +
    1.83      /**
    1.84       * Sets the name of the dynamic fragment.
    1.85 -     * 
    1.86 +     * <p>
    1.87       * It is sufficient to specify the name without any extension. The extension
    1.88       * is added automatically if not specified.
    1.89 -     * 
    1.90 +     * <p>
    1.91       * The fragment must be located in the dynamic fragments folder.
    1.92 -     * 
    1.93 -     * @param req the servlet request object
    1.94 +     *
    1.95 +     * @param req          the servlet request object
    1.96       * @param fragmentName the name of the fragment
    1.97       * @see Constants#DYN_FRAGMENT_PATH_PREFIX
    1.98       */
    1.99      public void setDynamicFragment(HttpServletRequest req, String fragmentName) {
   1.100          req.setAttribute(Constants.REQ_ATTR_FRAGMENT, Functions.dynFragmentPath(fragmentName));
   1.101      }
   1.102 -    
   1.103 +
   1.104      /**
   1.105       * Specifies the name of an additional stylesheet used by the module.
   1.106 -     * 
   1.107 +     * <p>
   1.108       * Setting an additional stylesheet is optional, but quite common for HTML
   1.109       * output.
   1.110 -     * 
   1.111 +     * <p>
   1.112       * It is sufficient to specify the name without any extension. The extension
   1.113       * is added automatically if not specified.
   1.114 -     * 
   1.115 -     * @param req the servlet request object
   1.116 +     *
   1.117 +     * @param req        the servlet request object
   1.118       * @param stylesheet the name of the stylesheet
   1.119       */
   1.120      public void setStylesheet(HttpServletRequest req, String stylesheet) {
   1.121          req.setAttribute(Constants.REQ_ATTR_STYLESHEET, Functions.enforceExt(stylesheet, ".css"));
   1.122      }
   1.123 -    
   1.124 +
   1.125      private void forwardToFullView(HttpServletRequest req, HttpServletResponse resp)
   1.126              throws IOException, ServletException {
   1.127 -        
   1.128 +
   1.129          req.setAttribute(Constants.REQ_ATTR_MENU, getModuleManager().getMainMenu(getDatabaseFacade()));
   1.130          req.getRequestDispatcher(HTML_FULL_DISPATCHER).forward(req, resp);
   1.131      }
   1.132 -    
   1.133 +
   1.134      private Optional<HandlerMethod> findMapping(HttpMethod method, HttpServletRequest req) {
   1.135          return Optional.ofNullable(mappings.get(method)).map(
   1.136                  (rm) -> rm.get(Optional.ofNullable(req.getPathInfo()).orElse("/"))
   1.137          );
   1.138      }
   1.139 -    
   1.140 -    private void forwardAsSepcified(ResponseType type, HttpServletRequest req, HttpServletResponse resp)
   1.141 +
   1.142 +    private void forwardAsSpecified(ResponseType type, HttpServletRequest req, HttpServletResponse resp)
   1.143              throws ServletException, IOException {
   1.144          switch (type) {
   1.145 -            case NONE: return;
   1.146 +            case NONE:
   1.147 +                return;
   1.148              case HTML_FULL:
   1.149                  forwardToFullView(req, resp);
   1.150                  return;
   1.151              // TODO: implement remaining response types
   1.152              default:
   1.153 -                // this code should be unreachable
   1.154 -                LOG.error("ResponseType switch is not exhaustive - this is a bug!");
   1.155 -                throw new UnsupportedOperationException();
   1.156 +                throw new AssertionError("ResponseType switch is not exhaustive - this is a bug!");
   1.157          }
   1.158      }
   1.159 -    
   1.160 +
   1.161      private void doProcess(HttpMethod method, HttpServletRequest req, HttpServletResponse resp)
   1.162              throws ServletException, IOException {
   1.163  
   1.164          // Synchronize module information with database
   1.165          getModuleManager().syncWithDatabase(getDatabaseFacade());
   1.166 -        
   1.167 +
   1.168          // choose the requested language as session language (if available) or fall back to english, otherwise
   1.169          HttpSession session = req.getSession();
   1.170          if (session.getAttribute(Constants.SESSION_ATTR_LANGUAGE) == null) {
   1.171 @@ -261,28 +265,28 @@
   1.172              Optional<Locale> reqLocale = Optional.of(req.getLocale());
   1.173              Locale sessionLocale = reqLocale.filter((rl) -> availableLanguages.map((al) -> al.contains(rl.getLanguage())).orElse(false)).orElse(Locale.ENGLISH);
   1.174              session.setAttribute(Constants.SESSION_ATTR_LANGUAGE, sessionLocale);
   1.175 -            LOG.debug("Settng language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage());
   1.176 +            LOG.debug("Setting language for new session {}: {}", session.getId(), sessionLocale.getDisplayLanguage());
   1.177          } else {
   1.178              Locale sessionLocale = (Locale) session.getAttribute(Constants.SESSION_ATTR_LANGUAGE);
   1.179              resp.setLocale(sessionLocale);
   1.180              LOG.trace("Continuing session {} with language {}", session.getId(), sessionLocale);
   1.181          }
   1.182 -        
   1.183 +
   1.184          // set some internal request attributes
   1.185          req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req));
   1.186          req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName());
   1.187          Optional.ofNullable(moduleInfoELProxy).ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy));
   1.188 -        
   1.189 -        
   1.190 +
   1.191 +
   1.192          // call the handler, if available, or send an HTTP 404 error
   1.193          Optional<HandlerMethod> mapping = findMapping(method, req);
   1.194          if (mapping.isPresent()) {
   1.195 -            forwardAsSepcified(mapping.get().apply(req, resp), req, resp);
   1.196 +            forwardAsSpecified(mapping.get().apply(req, resp), req, resp);
   1.197          } else {
   1.198              resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   1.199          }
   1.200      }
   1.201 -    
   1.202 +
   1.203      @Override
   1.204      protected final void doGet(HttpServletRequest req, HttpServletResponse resp)
   1.205              throws ServletException, IOException {
     2.1 --- a/src/main/java/de/uapcore/lightpit/Constants.java	Sat May 09 15:19:21 2020 +0200
     2.2 +++ b/src/main/java/de/uapcore/lightpit/Constants.java	Sat May 09 17:01:29 2020 +0200
     2.3 @@ -1,8 +1,8 @@
     2.4  /*
     2.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 - * 
     2.7 + *
     2.8   * Copyright 2018 Mike Becker. All rights reserved.
     2.9 - * 
    2.10 + *
    2.11   * Redistribution and use in source and binary forms, with or without
    2.12   * modification, are permitted provided that the following conditions are met:
    2.13   *
    2.14 @@ -24,7 +24,7 @@
    2.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    2.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    2.17   * POSSIBILITY OF SUCH DAMAGE.
    2.18 - * 
    2.19 + *
    2.20   */
    2.21  package de.uapcore.lightpit;
    2.22  
    2.23 @@ -32,52 +32,52 @@
    2.24  
    2.25  /**
    2.26   * Contains all non-local scope constants used by the this application.
    2.27 - * 
    2.28 + * <p>
    2.29   * Constants with (class) local scope are defined in their respective classes.
    2.30   */
    2.31  public final class Constants {
    2.32      public static final String JSP_PATH_PREFIX = "/WEB-INF/jsp/";
    2.33 -    
    2.34 +
    2.35      public static final String JSPF_PATH_PREFIX = "/WEB-INF/jspf/";
    2.36 -    
    2.37 +
    2.38      public static final String DYN_FRAGMENT_PATH_PREFIX = "/WEB-INF/dynamic_fragments/";
    2.39 -    
    2.40 -    
    2.41 +
    2.42 +
    2.43      /**
    2.44       * Name for the context parameter specifying the available languages.
    2.45       */
    2.46      public static final String CTX_ATTR_LANGUAGES = "available-languages";
    2.47 -    
    2.48 +
    2.49      /**
    2.50       * Name for the context parameter optionally specifying the JNDI context;
    2.51       */
    2.52      public static final String CTX_ATTR_JNDI_CONTEXT = "jndi-context";
    2.53 -    
    2.54 +
    2.55      /**
    2.56       * Name for the context parameter optionally specifying a database schema.
    2.57       */
    2.58      public static final String CTX_ATTR_DB_SCHEMA = "db-schema";
    2.59 -    
    2.60 +
    2.61      /**
    2.62       * Name for the context parameter optionally specifying a database dialect.
    2.63       */
    2.64      public static final String CTX_ATTR_DB_DIALECT = "db-dialect";
    2.65 -    
    2.66 +
    2.67      /**
    2.68       * Key for the request attribute containing the class name of the currently dispatching module.
    2.69       */
    2.70      public static final String REQ_ATTR_MODULE_CLASSNAME = fqn(AbstractLightPITServlet.class, "moduleClassname");
    2.71 -    
    2.72 +
    2.73      /**
    2.74       * Key for the request attribute containing the {@link LightPITModule} information of the currently dispatching module.
    2.75       */
    2.76      public static final String REQ_ATTR_MODULE_INFO = fqn(AbstractLightPITServlet.class, "moduleInfo");
    2.77 -    
    2.78 +
    2.79      /**
    2.80       * Key for the request attribute containing the menu list.
    2.81       */
    2.82      public static final String REQ_ATTR_MENU = fqn(AbstractLightPITServlet.class, "mainMenu");
    2.83 -    
    2.84 +
    2.85      /**
    2.86       * Key for the request attribute containing the full path information (servlet path + path info).
    2.87       */
    2.88 @@ -85,22 +85,23 @@
    2.89  
    2.90      /**
    2.91       * Key for the name of the fragment which should be rendered.
    2.92 -     */    
    2.93 +     */
    2.94      public static final String REQ_ATTR_FRAGMENT = fqn(AbstractLightPITServlet.class, "fragment");
    2.95 -    
    2.96 +
    2.97      /**
    2.98       * Key for the name of the additional stylesheet used by a module.
    2.99 -     */    
   2.100 +     */
   2.101      public static final String REQ_ATTR_STYLESHEET = fqn(AbstractLightPITServlet.class, "extraCss");
   2.102 -    
   2.103 -    
   2.104 +
   2.105 +
   2.106      /**
   2.107       * Key for the current language selection within the session.
   2.108       */
   2.109      public static final String SESSION_ATTR_LANGUAGE = fqn(AbstractLightPITServlet.class, "language");
   2.110 -    
   2.111 +
   2.112      /**
   2.113       * This class is not instantiatable.
   2.114       */
   2.115 -    private Constants() {}
   2.116 +    private Constants() {
   2.117 +    }
   2.118  }
     3.1 --- a/src/main/java/de/uapcore/lightpit/DatabaseFacade.java	Sat May 09 15:19:21 2020 +0200
     3.2 +++ b/src/main/java/de/uapcore/lightpit/DatabaseFacade.java	Sat May 09 17:01:29 2020 +0200
     3.3 @@ -1,8 +1,8 @@
     3.4  /*
     3.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 - * 
     3.7 + *
     3.8   * Copyright 2018 Mike Becker. All rights reserved.
     3.9 - * 
    3.10 + *
    3.11   * Redistribution and use in source and binary forms, with or without
    3.12   * modification, are permitted provided that the following conditions are met:
    3.13   *
    3.14 @@ -24,10 +24,12 @@
    3.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.17   * POSSIBILITY OF SUCH DAMAGE.
    3.18 - * 
    3.19 + *
    3.20   */
    3.21  package de.uapcore.lightpit;
    3.22  
    3.23 +import de.uapcore.lightpit.dao.DataAccessObjects;
    3.24 +import de.uapcore.lightpit.dao.postgres.PGDataAccessObjects;
    3.25  import org.slf4j.Logger;
    3.26  import org.slf4j.LoggerFactory;
    3.27  
    3.28 @@ -57,6 +59,9 @@
    3.29       */
    3.30      private static final int DB_TEST_TIMEOUT = 10;
    3.31  
    3.32 +    /**
    3.33 +     * Specifies the database dialect.
    3.34 +     */
    3.35      public enum Dialect {
    3.36          Postgres
    3.37      }
    3.38 @@ -64,21 +69,21 @@
    3.39      /**
    3.40       * The database dialect to use.
    3.41       * <p>
    3.42 -     * May be override by context parameter.
    3.43 +     * May be overridden by context parameter.
    3.44       *
    3.45       * @see Constants#CTX_ATTR_DB_DIALECT
    3.46       */
    3.47      private Dialect dialect = Dialect.Postgres;
    3.48 -    
    3.49 +
    3.50      /**
    3.51       * The default schema to test against when validating the connection.
    3.52 -     * 
    3.53 +     * <p>
    3.54       * May be overridden by context parameter.
    3.55 -     * 
    3.56 +     *
    3.57       * @see Constants#CTX_ATTR_DB_SCHEMA
    3.58       */
    3.59      private static final String DB_DEFAULT_SCHEMA = "lightpit";
    3.60 -    
    3.61 +
    3.62      /**
    3.63       * The attribute name in the Servlet context under which an instance of this class can be found.
    3.64       */
    3.65 @@ -86,21 +91,31 @@
    3.66  
    3.67      private static final String DS_JNDI_NAME = "jdbc/lightpit/app";
    3.68      private DataSource dataSource;
    3.69 -    
    3.70 +    private DataAccessObjects dataAccessObjects;
    3.71 +
    3.72      /**
    3.73       * Returns the data source.
    3.74 -     * 
    3.75 +     * <p>
    3.76       * The Optional returned should never be empty. However, if something goes
    3.77       * wrong during initialization, the data source might be absent.
    3.78       * Hence, users of this data source are forced to check the existence.
    3.79 -     * 
    3.80 +     *
    3.81       * @return a data source
    3.82       */
    3.83      public Optional<DataSource> getDataSource() {
    3.84          // TODO: this should not be an optional, if an empty optional is actually an exception
    3.85          return Optional.ofNullable(dataSource);
    3.86      }
    3.87 -    
    3.88 +
    3.89 +    /**
    3.90 +     * Returns the data access objects.
    3.91 +     *
    3.92 +     * @return an interface to obtain the data access objects
    3.93 +     */
    3.94 +    public DataAccessObjects getDataAccessObjects() {
    3.95 +        return dataAccessObjects;
    3.96 +    }
    3.97 +
    3.98      public Dialect getSQLDialect() {
    3.99          return dialect;
   3.100      }
   3.101 @@ -138,9 +153,9 @@
   3.102      @Override
   3.103      public void contextInitialized(ServletContextEvent sce) {
   3.104          ServletContext sc = sce.getServletContext();
   3.105 -        
   3.106 +
   3.107          dataSource = null;
   3.108 -        
   3.109 +
   3.110          final String contextName = Optional
   3.111                  .ofNullable(sc.getInitParameter(Constants.CTX_ATTR_JNDI_CONTEXT))
   3.112                  .orElse("java:comp/env");
   3.113 @@ -156,6 +171,8 @@
   3.114              }
   3.115          }
   3.116  
   3.117 +        dataAccessObjects = createDataAccessObjects(dialect);
   3.118 +
   3.119          try {
   3.120              LOG.debug("Trying to access JNDI context {}...", contextName);
   3.121              Context initialCtx = new InitialContext();
   3.122 @@ -169,13 +186,22 @@
   3.123          } catch (NamingException | ClassCastException ex) {
   3.124              LOG.error("Cannot access JNDI resources.", ex);
   3.125          }
   3.126 -        
   3.127 +
   3.128          sc.setAttribute(SC_ATTR_NAME, this);
   3.129          LOG.info("Database facade injected into ServletContext.");
   3.130      }
   3.131  
   3.132 +    private static DataAccessObjects createDataAccessObjects(Dialect dialect) {
   3.133 +        switch (dialect) {
   3.134 +            case Postgres:
   3.135 +                return new PGDataAccessObjects();
   3.136 +            default:
   3.137 +                throw new AssertionError("Non-exhaustive switch - this is a bug.");
   3.138 +        }
   3.139 +    }
   3.140 +
   3.141      @Override
   3.142      public void contextDestroyed(ServletContextEvent sce) {
   3.143          dataSource = null;
   3.144 -    }    
   3.145 +    }
   3.146  }
     4.1 --- a/src/main/java/de/uapcore/lightpit/Functions.java	Sat May 09 15:19:21 2020 +0200
     4.2 +++ b/src/main/java/de/uapcore/lightpit/Functions.java	Sat May 09 17:01:29 2020 +0200
     4.3 @@ -1,8 +1,8 @@
     4.4  /*
     4.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 - * 
     4.7 + *
     4.8   * Copyright 2018 Mike Becker. All rights reserved.
     4.9 - * 
    4.10 + *
    4.11   * Redistribution and use in source and binary forms, with or without
    4.12   * modification, are permitted provided that the following conditions are met:
    4.13   *
    4.14 @@ -24,7 +24,7 @@
    4.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    4.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    4.17   * POSSIBILITY OF SUCH DAMAGE.
    4.18 - * 
    4.19 + *
    4.20   */
    4.21  package de.uapcore.lightpit;
    4.22  
    4.23 @@ -39,13 +39,13 @@
    4.24   * Contains common static functions.
    4.25   */
    4.26  public final class Functions {
    4.27 -    
    4.28 +
    4.29      private static final Logger LOG = LoggerFactory.getLogger(Functions.class);
    4.30  
    4.31      public static Optional<String[]> availableLanguages(ServletContext ctx) {
    4.32          return Optional.ofNullable(ctx.getInitParameter(Constants.CTX_ATTR_LANGUAGES)).map((x) -> x.split("\\s*,\\s*"));
    4.33      }
    4.34 -    
    4.35 +
    4.36      public static String enforceExt(String filename, String ext) {
    4.37          return filename.endsWith(ext) ? filename : filename + ext;
    4.38      }
    4.39 @@ -53,23 +53,23 @@
    4.40      public static String jspPath(String filename) {
    4.41          return enforceExt(Constants.JSP_PATH_PREFIX + filename, ".jsp");
    4.42      }
    4.43 -    
    4.44 +
    4.45      public static String jspfPath(String filename) {
    4.46          return enforceExt(Constants.JSPF_PATH_PREFIX + filename, ".jspf");
    4.47      }
    4.48 -    
    4.49 +
    4.50      public static String dynFragmentPath(String filename) {
    4.51          return enforceExt(Constants.DYN_FRAGMENT_PATH_PREFIX + filename, ".jsp");
    4.52      }
    4.53 -    
    4.54 +
    4.55      public static String fqn(String base, String name) {
    4.56 -        return base+"."+name;
    4.57 +        return base + "." + name;
    4.58      }
    4.59  
    4.60      public static String fqn(Class<?> clazz, String name) {
    4.61          return fqn(clazz.getName(), name);
    4.62      }
    4.63 -    
    4.64 +
    4.65      public static String fullPath(LightPITModule module, RequestMapping mapping) {
    4.66          StringBuilder sb = new StringBuilder();
    4.67          sb.append(module.modulePath());
    4.68 @@ -80,17 +80,17 @@
    4.69          }
    4.70          return sb.toString();
    4.71      }
    4.72 -    
    4.73 +
    4.74      public static String fullPath(HttpServletRequest req) {
    4.75          return req.getServletPath() + Optional.ofNullable(req.getPathInfo()).orElse("");
    4.76      }
    4.77 -    
    4.78 +
    4.79      /**
    4.80       * Returns the module path of the given LightPIT Servlet module.
    4.81 -     * 
    4.82 +     * <p>
    4.83       * If you specify a malformed LightPIT servlet, which does not have a module
    4.84       * annotation, the path to the <code>/error/404.html</code> page is returned.
    4.85 -     * 
    4.86 +     *
    4.87       * @param clazz the servlet class
    4.88       * @return the module path
    4.89       */
    4.90 @@ -106,9 +106,10 @@
    4.91              return "/error/404.html";
    4.92          }
    4.93      }
    4.94 -    
    4.95 +
    4.96      /**
    4.97       * This class is not instantiatable.
    4.98       */
    4.99 -    private Functions() {}
   4.100 +    private Functions() {
   4.101 +    }
   4.102  }
     5.1 --- a/src/main/java/de/uapcore/lightpit/HttpMethod.java	Sat May 09 15:19:21 2020 +0200
     5.2 +++ b/src/main/java/de/uapcore/lightpit/HttpMethod.java	Sat May 09 17:01:29 2020 +0200
     5.3 @@ -1,8 +1,8 @@
     5.4  /*
     5.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 - * 
     5.7 + *
     5.8   * Copyright 2018 Mike Becker. All rights reserved.
     5.9 - * 
    5.10 + *
    5.11   * Redistribution and use in source and binary forms, with or without
    5.12   * modification, are permitted provided that the following conditions are met:
    5.13   *
    5.14 @@ -24,7 +24,7 @@
    5.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    5.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    5.17   * POSSIBILITY OF SUCH DAMAGE.
    5.18 - * 
    5.19 + *
    5.20   */
    5.21  package de.uapcore.lightpit;
    5.22  
     6.1 --- a/src/main/java/de/uapcore/lightpit/LightPITModule.java	Sat May 09 15:19:21 2020 +0200
     6.2 +++ b/src/main/java/de/uapcore/lightpit/LightPITModule.java	Sat May 09 17:01:29 2020 +0200
     6.3 @@ -1,8 +1,8 @@
     6.4  /*
     6.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 - * 
     6.7 + *
     6.8   * Copyright 2018 Mike Becker. All rights reserved.
     6.9 - * 
    6.10 + *
    6.11   * Redistribution and use in source and binary forms, with or without
    6.12   * modification, are permitted provided that the following conditions are met:
    6.13   *
    6.14 @@ -24,7 +24,7 @@
    6.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    6.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    6.17   * POSSIBILITY OF SUCH DAMAGE.
    6.18 - * 
    6.19 + *
    6.20   */
    6.21  package de.uapcore.lightpit;
    6.22  
    6.23 @@ -34,7 +34,7 @@
    6.24  
    6.25  /**
    6.26   * Contains information about a LightPIT module.
    6.27 - * 
    6.28 + * <p>
    6.29   * This annotation is typically used to annotate the {@link WebServlet} which
    6.30   * implements the module's functionality.
    6.31   */
    6.32 @@ -44,57 +44,59 @@
    6.33  public @interface LightPITModule {
    6.34      /**
    6.35       * Base name of the module specific resource bundle.
    6.36 +     *
    6.37       * @return a base name suitable for the JSTL tag 'setBundle'.
    6.38       */
    6.39      String bundleBaseName();
    6.40 -    
    6.41 +
    6.42      /**
    6.43       * An array of required modules, identified by the string representation of
    6.44       * their class names.
    6.45 +     *
    6.46       * @return an array of class names of required modules
    6.47       */
    6.48      String[] requires() default {};
    6.49 -    
    6.50 +
    6.51      /**
    6.52       * The path for this module, which will also be used for the menu entry.
    6.53 -     * 
    6.54 +     * <p>
    6.55       * This path must adhere to the URL pattern of the Servlet but must not
    6.56       * contain any starting or trailing slashes.
    6.57 -     * 
    6.58 +     *
    6.59       * @return the relative module path
    6.60       */
    6.61      String modulePath();
    6.62 -    
    6.63 +
    6.64      /**
    6.65       * Returns the properties key for the module name.
    6.66 -     * 
    6.67 +     *
    6.68       * @return the properties key
    6.69       */
    6.70      String nameKey() default "name";
    6.71 -    
    6.72 +
    6.73      /**
    6.74       * Returns the properties key for the module description.
    6.75 -     * 
    6.76 +     *
    6.77       * @return the properties key
    6.78       */
    6.79      String descKey() default "description";
    6.80 -    
    6.81 -    
    6.82 +
    6.83 +
    6.84      /**
    6.85       * Returns the properties key for the menu label.
    6.86 -     * 
    6.87 +     * <p>
    6.88       * Set this string to empty string, if the module should be hidden from
    6.89       * the menu.
    6.90 -     * 
    6.91 +     *
    6.92       * @return the properties key
    6.93       */
    6.94      String menuKey() default "menuLabel";
    6.95 -    
    6.96 +
    6.97      /**
    6.98       * Returns the properties key for the page title.
    6.99 -     * 
   6.100 +     * <p>
   6.101       * By default this is the same as the menu label.
   6.102 -     * 
   6.103 +     *
   6.104       * @return the properties key
   6.105       */
   6.106      String titleKey() default "menuLabel";
   6.107 @@ -169,6 +171,6 @@
   6.108          public String getDescKey() {
   6.109              return descKey;
   6.110          }
   6.111 -        
   6.112 +
   6.113      }
   6.114  }
     7.1 --- a/src/main/java/de/uapcore/lightpit/Menu.java	Sat May 09 15:19:21 2020 +0200
     7.2 +++ b/src/main/java/de/uapcore/lightpit/Menu.java	Sat May 09 17:01:29 2020 +0200
     7.3 @@ -1,8 +1,8 @@
     7.4  /*
     7.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     7.6 - * 
     7.7 + *
     7.8   * Copyright 2018 Mike Becker. All rights reserved.
     7.9 - * 
    7.10 + *
    7.11   * Redistribution and use in source and binary forms, with or without
    7.12   * modification, are permitted provided that the following conditions are met:
    7.13   *
    7.14 @@ -24,7 +24,7 @@
    7.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    7.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    7.17   * POSSIBILITY OF SUCH DAMAGE.
    7.18 - * 
    7.19 + *
    7.20   */
    7.21  package de.uapcore.lightpit;
    7.22  
    7.23 @@ -35,30 +35,30 @@
    7.24  /**
    7.25   * Maps a resource key for the menu label to the path name for the underlying
    7.26   * site.
    7.27 - * 
    7.28 + * <p>
    7.29   * Objects of this class are internally instantiated by the
    7.30   * {@link ModuleManager}.
    7.31   */
    7.32  public class Menu extends MenuEntry {
    7.33 -    
    7.34 +
    7.35      private final List<MenuEntry> entries = new ArrayList<>();
    7.36      private final List<MenuEntry> immutableEntries = Collections.unmodifiableList(entries);
    7.37 -    
    7.38 +
    7.39      /**
    7.40       * Class name of the module for which this menu is built.
    7.41       */
    7.42      private String moduleClassName;
    7.43 -    
    7.44 -    
    7.45 +
    7.46 +
    7.47      public Menu() {
    7.48          super();
    7.49      }
    7.50 -    
    7.51 +
    7.52      public Menu(String moduleClassName, ResourceKey resourceKey, String pathName) {
    7.53          super(resourceKey, pathName);
    7.54          this.moduleClassName = moduleClassName;
    7.55      }
    7.56 -    
    7.57 +
    7.58      public void setModuleClassName(String moduleClassName) {
    7.59          this.moduleClassName = moduleClassName;
    7.60      }
    7.61 @@ -69,7 +69,7 @@
    7.62  
    7.63      /**
    7.64       * Sets a new list of menu entries for this menu.
    7.65 -     * 
    7.66 +     *
    7.67       * @param entries the list of new menu entries
    7.68       */
    7.69      public void setEntries(List<MenuEntry> entries) {
    7.70 @@ -80,15 +80,16 @@
    7.71  
    7.72      /**
    7.73       * Retrieves an immutable list of menu entries for this menu.
    7.74 -     * 
    7.75 +     *
    7.76       * @return the list of menu entries
    7.77       */
    7.78      public List<MenuEntry> getEntries() {
    7.79          return immutableEntries;
    7.80      }
    7.81 -    
    7.82 +
    7.83      /**
    7.84       * Adds a new menu entry to this menu.
    7.85 +     *
    7.86       * @param entry the menu entry to add
    7.87       */
    7.88      public void addMenuEntry(MenuEntry entry) {
     8.1 --- a/src/main/java/de/uapcore/lightpit/MenuEntry.java	Sat May 09 15:19:21 2020 +0200
     8.2 +++ b/src/main/java/de/uapcore/lightpit/MenuEntry.java	Sat May 09 17:01:29 2020 +0200
     8.3 @@ -1,8 +1,8 @@
     8.4  /*
     8.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     8.6 - * 
     8.7 + *
     8.8   * Copyright 2018 Mike Becker. All rights reserved.
     8.9 - * 
    8.10 + *
    8.11   * Redistribution and use in source and binary forms, with or without
    8.12   * modification, are permitted provided that the following conditions are met:
    8.13   *
    8.14 @@ -24,24 +24,24 @@
    8.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    8.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    8.17   * POSSIBILITY OF SUCH DAMAGE.
    8.18 - * 
    8.19 + *
    8.20   */
    8.21  package de.uapcore.lightpit;
    8.22  
    8.23  /**
    8.24   * Maps a resource key for the menu label to the path name for the underlying
    8.25   * site.
    8.26 - * 
    8.27 + * <p>
    8.28   * Objects of this class are internally instantiated by the
    8.29   * {@link ModuleManager}.
    8.30   */
    8.31  public class MenuEntry {
    8.32 -    
    8.33 +
    8.34      /**
    8.35       * Resource key for the menu label.
    8.36       */
    8.37      private ResourceKey resourceKey;
    8.38 -    
    8.39 +
    8.40      /**
    8.41       * Path name of the module, linked by this menu entry.
    8.42       */
    8.43 @@ -70,5 +70,5 @@
    8.44      public String getPathName() {
    8.45          return pathName;
    8.46      }
    8.47 -    
    8.48 +
    8.49  }
     9.1 --- a/src/main/java/de/uapcore/lightpit/ModuleManager.java	Sat May 09 15:19:21 2020 +0200
     9.2 +++ b/src/main/java/de/uapcore/lightpit/ModuleManager.java	Sat May 09 17:01:29 2020 +0200
     9.3 @@ -1,8 +1,8 @@
     9.4  /*
     9.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     9.6 - * 
     9.7 + *
     9.8   * Copyright 2018 Mike Becker. All rights reserved.
     9.9 - * 
    9.10 + *
    9.11   * Redistribution and use in source and binary forms, with or without
    9.12   * modification, are permitted provided that the following conditions are met:
    9.13   *
    9.14 @@ -24,12 +24,10 @@
    9.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    9.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    9.17   * POSSIBILITY OF SUCH DAMAGE.
    9.18 - * 
    9.19 + *
    9.20   */
    9.21  package de.uapcore.lightpit;
    9.22  
    9.23 -import de.uapcore.lightpit.dao.CoreDAOFactory;
    9.24 -import de.uapcore.lightpit.dao.ModuleDao;
    9.25  import de.uapcore.lightpit.entities.Module;
    9.26  import org.slf4j.Logger;
    9.27  import org.slf4j.LoggerFactory;
    9.28 @@ -50,25 +48,25 @@
    9.29   */
    9.30  @WebListener
    9.31  public final class ModuleManager implements ServletContextListener {
    9.32 -    
    9.33 +
    9.34      private static final Logger LOG = LoggerFactory.getLogger(ModuleManager.class);
    9.35 -    
    9.36 +
    9.37      /**
    9.38       * The attribute name in the servlet context under which an instance of this class can be found.
    9.39       */
    9.40      public static final String SC_ATTR_NAME = ModuleManager.class.getName();
    9.41      private ServletContext sc;
    9.42 -    
    9.43 +
    9.44      /**
    9.45       * Maps class names to module information.
    9.46       */
    9.47      private final Map<String, LightPITModule> registeredModules = new HashMap<>();
    9.48 -    
    9.49 +
    9.50      /**
    9.51       * This flag is true, when synchronization is needed.
    9.52       */
    9.53      private final AtomicBoolean dirty = new AtomicBoolean(true);
    9.54 -    
    9.55 +
    9.56      @Override
    9.57      public void contextInitialized(ServletContextEvent sce) {
    9.58          sc = sce.getServletContext();
    9.59 @@ -81,27 +79,27 @@
    9.60      public void contextDestroyed(ServletContextEvent sce) {
    9.61          unloadAll();
    9.62      }
    9.63 -    
    9.64 +
    9.65      private Optional<LightPITModule> getModuleInfo(Registration reg) {
    9.66          try {
    9.67              final Class<?> scclass = Class.forName(reg.getClassName());
    9.68 -            
    9.69 +
    9.70              final boolean lpservlet = AbstractLightPITServlet.class.isAssignableFrom(scclass);
    9.71              final boolean lpmodule = scclass.isAnnotationPresent(LightPITModule.class);
    9.72 -            
    9.73 +
    9.74              if (lpservlet && !lpmodule) {
    9.75                  LOG.warn(
    9.76 -                    "{} is a LightPIT Servlet but is missing the module annotation.",
    9.77 -                    reg.getClassName()
    9.78 +                        "{} is a LightPIT Servlet but is missing the module annotation.",
    9.79 +                        reg.getClassName()
    9.80                  );
    9.81              } else if (!lpservlet && lpmodule) {
    9.82                  LOG.warn(
    9.83 -                    "{} is annotated as a LightPIT Module but does not extend {}.",
    9.84 -                    reg.getClassName(),
    9.85 -                    AbstractLightPITServlet.class.getSimpleName()
    9.86 +                        "{} is annotated as a LightPIT Module but does not extend {}.",
    9.87 +                        reg.getClassName(),
    9.88 +                        AbstractLightPITServlet.class.getSimpleName()
    9.89                  );
    9.90              }
    9.91 -            
    9.92 +
    9.93              if (lpservlet && lpmodule) {
    9.94                  final LightPITModule moduleInfo = scclass.getAnnotation(LightPITModule.class);
    9.95                  return Optional.of(moduleInfo);
    9.96 @@ -115,28 +113,28 @@
    9.97                      ex.getMessage()
    9.98              );
    9.99              return Optional.empty();
   9.100 -        }        
   9.101 +        }
   9.102      }
   9.103 -    
   9.104 +
   9.105      private void handleServletRegistration(String name, Registration reg) {
   9.106          final Optional<LightPITModule> moduleInfo = getModuleInfo(reg);
   9.107          if (moduleInfo.isPresent()) {
   9.108 -            registeredModules.put(reg.getClassName(), moduleInfo.get());            
   9.109 +            registeredModules.put(reg.getClassName(), moduleInfo.get());
   9.110              LOG.info("Module detected: {}", name);
   9.111          } else {
   9.112              LOG.debug("Servlet {} is no module, skipping.", name);
   9.113          }
   9.114      }
   9.115 -    
   9.116 +
   9.117      /**
   9.118       * Scans for modules and reloads them all.
   9.119       */
   9.120      public void reloadAll() {
   9.121          registeredModules.clear();
   9.122          sc.getServletRegistrations().forEach(this::handleServletRegistration);
   9.123 -        
   9.124 +
   9.125          // TODO: implement dependency resolver
   9.126 -        
   9.127 +
   9.128          dirty.set(true);
   9.129          LOG.info("Modules loaded.");
   9.130      }
   9.131 @@ -157,8 +155,9 @@
   9.132          if (dirty.compareAndSet(true, false)) {
   9.133              if (db.getDataSource().isPresent()) {
   9.134                  try (Connection conn = db.getDataSource().get().getConnection()) {
   9.135 -                    final ModuleDao moduleDao = CoreDAOFactory.getModuleDao(db.getSQLDialect());
   9.136 -                    moduleDao.syncRegisteredModuleClasses(conn, registeredModules.entrySet());
   9.137 +                    db.getDataAccessObjects()
   9.138 +                            .getModuleDao()
   9.139 +                            .syncRegisteredModuleClasses(conn, registeredModules.entrySet());
   9.140                  } catch (SQLException ex) {
   9.141                      LOG.error("Unexpected SQL Exception", ex);
   9.142                  }
   9.143 @@ -169,7 +168,7 @@
   9.144              LOG.trace("Module information clean - no synchronization required.");
   9.145          }
   9.146      }
   9.147 -    
   9.148 +
   9.149      /**
   9.150       * Unloads all found modules.
   9.151       */
   9.152 @@ -180,17 +179,16 @@
   9.153  
   9.154      /**
   9.155       * Returns the main menu.
   9.156 -     * 
   9.157 +     *
   9.158       * @param db the interface to the database
   9.159       * @return a list of menus belonging to the main menu
   9.160       */
   9.161      public List<Menu> getMainMenu(DatabaseFacade db) {
   9.162          // TODO: user specific menu
   9.163 -        
   9.164 +
   9.165          if (db.getDataSource().isPresent()) {
   9.166              try (Connection conn = db.getDataSource().get().getConnection()) {
   9.167 -                final ModuleDao dao = CoreDAOFactory.getModuleDao(db.getSQLDialect());
   9.168 -                final List<Module> modules = dao.listAll(conn);
   9.169 +                final List<Module> modules = db.getDataAccessObjects().getModuleDao().list(conn);
   9.170  
   9.171                  return modules
   9.172                          .stream()
   9.173 @@ -211,12 +209,12 @@
   9.174              return Collections.emptyList();
   9.175          }
   9.176      }
   9.177 -    
   9.178 +
   9.179      /**
   9.180       * Returns an unmodifiable map of all registered modules.
   9.181 -     * 
   9.182 +     * <p>
   9.183       * The key is the classname of the module.
   9.184 -     * 
   9.185 +     *
   9.186       * @return the map of registered modules
   9.187       */
   9.188      public Map<String, LightPITModule> getRegisteredModules() {
    10.1 --- a/src/main/java/de/uapcore/lightpit/RequestMapping.java	Sat May 09 15:19:21 2020 +0200
    10.2 +++ b/src/main/java/de/uapcore/lightpit/RequestMapping.java	Sat May 09 17:01:29 2020 +0200
    10.3 @@ -1,8 +1,8 @@
    10.4  /*
    10.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    10.6 - * 
    10.7 + *
    10.8   * Copyright 2018 Mike Becker. All rights reserved.
    10.9 - * 
   10.10 + *
   10.11   * Redistribution and use in source and binary forms, with or without
   10.12   * modification, are permitted provided that the following conditions are met:
   10.13   *
   10.14 @@ -24,20 +24,16 @@
   10.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   10.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   10.17   * POSSIBILITY OF SUCH DAMAGE.
   10.18 - * 
   10.19 + *
   10.20   */
   10.21  package de.uapcore.lightpit;
   10.22  
   10.23 -import java.lang.annotation.Documented;
   10.24 -import java.lang.annotation.ElementType;
   10.25 -import java.lang.annotation.Retention;
   10.26 -import java.lang.annotation.RetentionPolicy;
   10.27 -import java.lang.annotation.Target;
   10.28 +import java.lang.annotation.*;
   10.29  
   10.30  
   10.31  /**
   10.32   * Maps requests to methods.
   10.33 - * 
   10.34 + * <p>
   10.35   * This annotation is used to annotate methods within classes which
   10.36   * override {@link AbstractLightPITServlet}.
   10.37   */
   10.38 @@ -45,31 +41,31 @@
   10.39  @Retention(RetentionPolicy.RUNTIME)
   10.40  @Target(ElementType.METHOD)
   10.41  public @interface RequestMapping {
   10.42 -    
   10.43 +
   10.44      /**
   10.45       * Specifies the HTTP method.
   10.46 -     * 
   10.47 +     *
   10.48       * @return the HTTP method handled by the annotated Java method
   10.49       */
   10.50      HttpMethod method();
   10.51  
   10.52      /**
   10.53       * Specifies the request path relative to the module path.
   10.54 -     * 
   10.55 +     * <p>
   10.56       * If a menu key is specified, this is also the path, which is linked
   10.57       * by the menu entry.
   10.58 -     * 
   10.59 +     * <p>
   10.60       * The path must be specified <em>without</em> leading and trailing slash.
   10.61 -     * 
   10.62 +     *
   10.63       * @return the request path the annotated method should handle
   10.64       */
   10.65      String requestPath() default "";
   10.66 -    
   10.67 +
   10.68      /**
   10.69       * Returns the properties key for the (sub) menu label.
   10.70 -     * 
   10.71 +     * <p>
   10.72       * This should only be used for {@link HttpMethod#GET} requests.
   10.73 -     * 
   10.74 +     *
   10.75       * @return the properties key
   10.76       */
   10.77      String menuKey() default "";
    11.1 --- a/src/main/java/de/uapcore/lightpit/ResourceKey.java	Sat May 09 15:19:21 2020 +0200
    11.2 +++ b/src/main/java/de/uapcore/lightpit/ResourceKey.java	Sat May 09 17:01:29 2020 +0200
    11.3 @@ -1,8 +1,8 @@
    11.4  /*
    11.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    11.6 - * 
    11.7 + *
    11.8   * Copyright 2018 Mike Becker. All rights reserved.
    11.9 - * 
   11.10 + *
   11.11   * Redistribution and use in source and binary forms, with or without
   11.12   * modification, are permitted provided that the following conditions are met:
   11.13   *
   11.14 @@ -24,7 +24,7 @@
   11.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   11.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.17   * POSSIBILITY OF SUCH DAMAGE.
   11.18 - * 
   11.19 + *
   11.20   */
   11.21  package de.uapcore.lightpit;
   11.22  
   11.23 @@ -34,9 +34,9 @@
   11.24  public final class ResourceKey {
   11.25      private String bundle;
   11.26      private String key;
   11.27 -    
   11.28 +
   11.29      public ResourceKey() {
   11.30 -        
   11.31 +
   11.32      }
   11.33  
   11.34      public ResourceKey(String bundle, String key) {
   11.35 @@ -55,7 +55,7 @@
   11.36      public void setKey(String key) {
   11.37          this.key = key;
   11.38      }
   11.39 -    
   11.40 +
   11.41      public String getKey() {
   11.42          return key;
   11.43      }
    12.1 --- a/src/main/java/de/uapcore/lightpit/ResponseType.java	Sat May 09 15:19:21 2020 +0200
    12.2 +++ b/src/main/java/de/uapcore/lightpit/ResponseType.java	Sat May 09 17:01:29 2020 +0200
    12.3 @@ -1,8 +1,8 @@
    12.4  /*
    12.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    12.6 - * 
    12.7 + *
    12.8   * Copyright 2018 Mike Becker. All rights reserved.
    12.9 - * 
   12.10 + *
   12.11   * Redistribution and use in source and binary forms, with or without
   12.12   * modification, are permitted provided that the following conditions are met:
   12.13   *
   12.14 @@ -24,7 +24,7 @@
   12.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   12.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   12.17   * POSSIBILITY OF SUCH DAMAGE.
   12.18 - * 
   12.19 + *
   12.20   */
   12.21  package de.uapcore.lightpit;
   12.22  
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/main/java/de/uapcore/lightpit/dao/AbstractDao.java	Sat May 09 17:01:29 2020 +0200
    13.3 @@ -0,0 +1,55 @@
    13.4 +/*
    13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 + *
    13.7 + * Copyright 2018 Mike Becker. All rights reserved.
    13.8 + *
    13.9 + * Redistribution and use in source and binary forms, with or without
   13.10 + * modification, are permitted provided that the following conditions are met:
   13.11 + *
   13.12 + *   1. Redistributions of source code must retain the above copyright
   13.13 + *      notice, this list of conditions and the following disclaimer.
   13.14 + *
   13.15 + *   2. Redistributions in binary form must reproduce the above copyright
   13.16 + *      notice, this list of conditions and the following disclaimer in the
   13.17 + *      documentation and/or other materials provided with the distribution.
   13.18 + *
   13.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   13.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   13.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   13.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   13.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   13.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   13.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   13.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   13.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   13.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   13.29 + * POSSIBILITY OF SUCH DAMAGE.
   13.30 + *
   13.31 + */
   13.32 +package de.uapcore.lightpit.dao;
   13.33 +
   13.34 +import java.sql.Connection;
   13.35 +import java.sql.PreparedStatement;
   13.36 +import java.sql.ResultSet;
   13.37 +import java.sql.SQLException;
   13.38 +import java.util.ArrayList;
   13.39 +import java.util.List;
   13.40 +
   13.41 +public abstract class AbstractDao<T> implements GenericDao<T> {
   13.42 +
   13.43 +    protected abstract PreparedStatement listQuery(Connection connection) throws SQLException;
   13.44 +
   13.45 +    protected abstract T mapColumns(ResultSet result) throws SQLException;
   13.46 +
   13.47 +    @Override
   13.48 +    public List<T> list(Connection conn) throws SQLException {
   13.49 +        List<T> list = new ArrayList<>();
   13.50 +        try (PreparedStatement stmt = listQuery(conn);
   13.51 +             ResultSet result = stmt.executeQuery()) {
   13.52 +            while (result.next()) {
   13.53 +                list.add(mapColumns(result));
   13.54 +            }
   13.55 +        }
   13.56 +        return list;
   13.57 +    }
   13.58 +}
    14.1 --- a/src/main/java/de/uapcore/lightpit/dao/CoreDAOFactory.java	Sat May 09 15:19:21 2020 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,49 +0,0 @@
    14.4 -/*
    14.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    14.6 - * 
    14.7 - * Copyright 2018 Mike Becker. All rights reserved.
    14.8 - * 
    14.9 - * Redistribution and use in source and binary forms, with or without
   14.10 - * modification, are permitted provided that the following conditions are met:
   14.11 - *
   14.12 - *   1. Redistributions of source code must retain the above copyright
   14.13 - *      notice, this list of conditions and the following disclaimer.
   14.14 - *
   14.15 - *   2. Redistributions in binary form must reproduce the above copyright
   14.16 - *      notice, this list of conditions and the following disclaimer in the
   14.17 - *      documentation and/or other materials provided with the distribution.
   14.18 - *
   14.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   14.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   14.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   14.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   14.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   14.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   14.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   14.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   14.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   14.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   14.29 - * POSSIBILITY OF SUCH DAMAGE.
   14.30 - * 
   14.31 - */
   14.32 -package de.uapcore.lightpit.dao;
   14.33 -
   14.34 -import de.uapcore.lightpit.DatabaseFacade;
   14.35 -
   14.36 -public final class CoreDAOFactory {
   14.37 -
   14.38 -    private static final ModuleDao moduleDao = new ModuleDao();
   14.39 -
   14.40 -    private CoreDAOFactory() {
   14.41 -    }
   14.42 -
   14.43 -    public static ModuleDao getModuleDao(DatabaseFacade.Dialect dialect) {
   14.44 -        // TODO: this is idiotic, we would not change the dialect while the app is running
   14.45 -        switch (dialect) {
   14.46 -            case Postgres:
   14.47 -                return moduleDao;
   14.48 -            default:
   14.49 -                throw new AssertionError("Switch was not exhaustive.");
   14.50 -        }
   14.51 -    }
   14.52 -}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java	Sat May 09 17:01:29 2020 +0200
    15.3 @@ -0,0 +1,36 @@
    15.4 +/*
    15.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    15.6 + *
    15.7 + * Copyright 2018 Mike Becker. All rights reserved.
    15.8 + *
    15.9 + * Redistribution and use in source and binary forms, with or without
   15.10 + * modification, are permitted provided that the following conditions are met:
   15.11 + *
   15.12 + *   1. Redistributions of source code must retain the above copyright
   15.13 + *      notice, this list of conditions and the following disclaimer.
   15.14 + *
   15.15 + *   2. Redistributions in binary form must reproduce the above copyright
   15.16 + *      notice, this list of conditions and the following disclaimer in the
   15.17 + *      documentation and/or other materials provided with the distribution.
   15.18 + *
   15.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   15.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   15.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   15.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   15.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   15.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   15.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   15.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   15.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   15.29 + * POSSIBILITY OF SUCH DAMAGE.
   15.30 + *
   15.31 + */
   15.32 +package de.uapcore.lightpit.dao;
   15.33 +
   15.34 +public interface DataAccessObjects {
   15.35 +
   15.36 +    ModuleDao getModuleDao();
   15.37 +
   15.38 +    UserDao getUserDao();
   15.39 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/main/java/de/uapcore/lightpit/dao/GenericDao.java	Sat May 09 17:01:29 2020 +0200
    16.3 @@ -0,0 +1,44 @@
    16.4 +/*
    16.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    16.6 + *
    16.7 + * Copyright 2018 Mike Becker. All rights reserved.
    16.8 + *
    16.9 + * Redistribution and use in source and binary forms, with or without
   16.10 + * modification, are permitted provided that the following conditions are met:
   16.11 + *
   16.12 + *   1. Redistributions of source code must retain the above copyright
   16.13 + *      notice, this list of conditions and the following disclaimer.
   16.14 + *
   16.15 + *   2. Redistributions in binary form must reproduce the above copyright
   16.16 + *      notice, this list of conditions and the following disclaimer in the
   16.17 + *      documentation and/or other materials provided with the distribution.
   16.18 + *
   16.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   16.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   16.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   16.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   16.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   16.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   16.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   16.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   16.29 + * POSSIBILITY OF SUCH DAMAGE.
   16.30 + *
   16.31 + */
   16.32 +package de.uapcore.lightpit.dao;
   16.33 +
   16.34 +import java.sql.Connection;
   16.35 +import java.sql.SQLException;
   16.36 +import java.util.List;
   16.37 +
   16.38 +public interface GenericDao<T> {
   16.39 +    /**
   16.40 +     * Returns a list of all entities.
   16.41 +     *
   16.42 +     * @param connection conn the connection to use
   16.43 +     * @return a list of all objects
   16.44 +     * @throws SQLException on any kind of SQL errors
   16.45 +     */
   16.46 +    List<T> list(Connection connection) throws SQLException;
   16.47 +}
    17.1 --- a/src/main/java/de/uapcore/lightpit/dao/ModuleDao.java	Sat May 09 15:19:21 2020 +0200
    17.2 +++ b/src/main/java/de/uapcore/lightpit/dao/ModuleDao.java	Sat May 09 17:01:29 2020 +0200
    17.3 @@ -1,8 +1,8 @@
    17.4  /*
    17.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    17.6 - * 
    17.7 + *
    17.8   * Copyright 2018 Mike Becker. All rights reserved.
    17.9 - * 
   17.10 + *
   17.11   * Redistribution and use in source and binary forms, with or without
   17.12   * modification, are permitted provided that the following conditions are met:
   17.13   *
   17.14 @@ -24,120 +24,29 @@
   17.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   17.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   17.17   * POSSIBILITY OF SUCH DAMAGE.
   17.18 - * 
   17.19 + *
   17.20   */
   17.21  package de.uapcore.lightpit.dao;
   17.22  
   17.23  import de.uapcore.lightpit.LightPITModule;
   17.24  import de.uapcore.lightpit.entities.Module;
   17.25  
   17.26 -import java.sql.*;
   17.27 -import java.util.ArrayList;
   17.28 -import java.util.List;
   17.29 +import java.sql.Connection;
   17.30 +import java.sql.SQLException;
   17.31  import java.util.Map;
   17.32  import java.util.Set;
   17.33  
   17.34 -public class ModuleDao {
   17.35 +public interface ModuleDao extends GenericDao<Module> {
   17.36  
   17.37      /**
   17.38 -     * Maps database columns to POJO fields.
   17.39 -     *
   17.40 -     * @param result the database result set
   17.41 -     * @param mod    the POJO
   17.42 -     * @throws SQLException on any kind of SQL errors
   17.43 -     */
   17.44 -    protected void mapColumns(ResultSet result, Module mod) throws SQLException {
   17.45 -        mod.setModID(result.getInt("modid"));
   17.46 -        mod.setClassname(result.getString("classname"));
   17.47 -        mod.setVisible(result.getBoolean("visible"));
   17.48 -        mod.setPriority(result.getInt("priority"));
   17.49 -    }
   17.50 -
   17.51 -
   17.52 -    /**
   17.53 -     * Must return a prepared statement for a single object query with the specified properties.
   17.54 -     *
   17.55 -     * <ul>
   17.56 -     * <li>Parameter 1: classname</li>
   17.57 -     * <li>Result field 1: visible</li>
   17.58 -     * </ul>
   17.59 -     *
   17.60 -     * @param conn the connection to use
   17.61 -     * @return the prepared statement
   17.62 -     * @throws SQLException on any kind of SQL errors
   17.63 -     */
   17.64 -    protected PreparedStatement moduleCheckStatement(Connection conn) throws SQLException {
   17.65 -        return conn.prepareStatement("SELECT visible FROM lpitcore_module WHERE classname = ?");
   17.66 -    }
   17.67 -
   17.68 -    /**
   17.69 -     * Must return a prepared statement for insertion with the specified properties.
   17.70 -     *
   17.71 -     * <ul>
   17.72 -     * <li>Parameter 1: classname</li>
   17.73 -     * <li>Parameter 2: visible</li>
   17.74 -     * <li>Parameter 3: priority</li>
   17.75 -     * </ul>
   17.76 -     *
   17.77 -     * @param conn the connection to use
   17.78 -     * @return the prepared statement
   17.79 -     * @throws SQLException on any kind of SQL errors
   17.80 -     */
   17.81 -    protected PreparedStatement moduleInsertStatement(Connection conn) throws SQLException {
   17.82 -        return conn.prepareStatement("INSERT INTO lpitcore_module (classname, visible, priority) VALUES (?, ?, ?)");
   17.83 -    }
   17.84 -    
   17.85 -    /**
   17.86       * Synchronizes a set of registered module classes with the database.
   17.87 -     *
   17.88 +     * <p>
   17.89       * Inserts module classes which are not known to the database and sets them to be visible by default.
   17.90       * Module classes known to the database, which are not in the given set, are ignored.
   17.91       *
   17.92 -     * @param conn the connection to use
   17.93 +     * @param conn      the connection to use
   17.94       * @param moduleSet the module set to synchronize
   17.95       * @throws SQLException on any kind of SQL errors
   17.96       */
   17.97 -    public final void syncRegisteredModuleClasses(Connection conn, Set<Map.Entry<String, LightPITModule>> moduleSet) throws SQLException {
   17.98 -                
   17.99 -        PreparedStatement
  17.100 -                check = moduleCheckStatement(conn),
  17.101 -                insert = moduleInsertStatement(conn);
  17.102 -        insert.setBoolean(2, true);
  17.103 -        // update/delete not required, we do this in the module management UI
  17.104 -
  17.105 -        for (Map.Entry<String, LightPITModule> modEntry : moduleSet) {
  17.106 -            if (modEntry.getValue().systemModule()) continue;
  17.107 -
  17.108 -            check.setString(1, modEntry.getKey());
  17.109 -            try (ResultSet r = check.executeQuery()) {
  17.110 -                if (!r.next()) {
  17.111 -                    insert.setString(1, modEntry.getKey());
  17.112 -                    insert.setInt(3, modEntry.getValue().defaultPriority());
  17.113 -                    insert.executeUpdate();
  17.114 -                }
  17.115 -            }
  17.116 -        }
  17.117 -    }
  17.118 -
  17.119 -    /**
  17.120 -     * Returns a list of all modules known by the database.
  17.121 -     *
  17.122 -     * Keep in mind, that system modules are never known to the database.
  17.123 -     *
  17.124 -     * @param conn the connection to use
  17.125 -     * @return a list of all modules known by the database
  17.126 -     * @throws SQLException on any kind of SQL errors
  17.127 -     */
  17.128 -    public List<Module> listAll(Connection conn) throws SQLException {
  17.129 -        List<Module> list = new ArrayList<>();
  17.130 -        try (Statement stmt = conn.createStatement();
  17.131 -                ResultSet result = stmt.executeQuery("SELECT * FROM lpitcore_module")) {
  17.132 -            while (result.next()) {
  17.133 -                final Module mod = new Module();
  17.134 -                mapColumns(result, mod);
  17.135 -                list.add(mod);
  17.136 -            }
  17.137 -        }
  17.138 -        return list;
  17.139 -    }
  17.140 +    void syncRegisteredModuleClasses(Connection conn, Set<Map.Entry<String, LightPITModule>> moduleSet) throws SQLException;
  17.141  }
    18.1 --- a/src/main/java/de/uapcore/lightpit/dao/UserDao.java	Sat May 09 15:19:21 2020 +0200
    18.2 +++ b/src/main/java/de/uapcore/lightpit/dao/UserDao.java	Sat May 09 17:01:29 2020 +0200
    18.3 @@ -1,8 +1,8 @@
    18.4  /*
    18.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    18.6 - * 
    18.7 + *
    18.8   * Copyright 2018 Mike Becker. All rights reserved.
    18.9 - * 
   18.10 + *
   18.11   * Redistribution and use in source and binary forms, with or without
   18.12   * modification, are permitted provided that the following conditions are met:
   18.13   *
   18.14 @@ -30,50 +30,6 @@
   18.15  
   18.16  import de.uapcore.lightpit.entities.User;
   18.17  
   18.18 -import java.sql.Connection;
   18.19 -import java.sql.ResultSet;
   18.20 -import java.sql.SQLException;
   18.21 -import java.sql.Statement;
   18.22 -import java.util.ArrayList;
   18.23 -import java.util.List;
   18.24 +public interface UserDao extends GenericDao<User> {
   18.25  
   18.26 -public class UserDao {
   18.27 -
   18.28 -    /**
   18.29 -     * Maps SQL columns to POJO fields.
   18.30 -     *
   18.31 -     * @param result the database result set
   18.32 -     * @param user   the POJO
   18.33 -     * @throws SQLException on any kind of SQL errors
   18.34 -     */
   18.35 -    protected void mapColumns(ResultSet result, User user) throws SQLException {
   18.36 -        user.setUserID(result.getInt("userid"));
   18.37 -        user.setUsername(result.getString("username"));
   18.38 -        user.setGivenname(result.getString("givenname"));
   18.39 -        user.setLastname(result.getString("lastname"));
   18.40 -    }
   18.41 -
   18.42 -    /**
   18.43 -     * Returns a list of all users ordered by their username.
   18.44 -     * <p>
   18.45 -     * Does not return reserved system users with negative user IDs.
   18.46 -     *
   18.47 -     * @param conn the connection to use
   18.48 -     * @return a list of all users
   18.49 -     * @throws SQLException on any kind of SQL errors
   18.50 -     */
   18.51 -    public List<User> listAll(Connection conn) throws SQLException {
   18.52 -        List<User> list = new ArrayList<>();
   18.53 -        try (
   18.54 -                Statement stmt = conn.createStatement();
   18.55 -                ResultSet result = stmt.executeQuery(
   18.56 -                        "SELECT * FROM lpitcore_user WHERE userid >= 0 ORDER BY username")) {
   18.57 -            while (result.next()) {
   18.58 -                final User user = new User();
   18.59 -                mapColumns(result, user);
   18.60 -                list.add(user);
   18.61 -            }
   18.62 -        }
   18.63 -        return list;
   18.64 -    }
   18.65  }
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java	Sat May 09 17:01:29 2020 +0200
    19.3 @@ -0,0 +1,49 @@
    19.4 +/*
    19.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    19.6 + *
    19.7 + * Copyright 2018 Mike Becker. All rights reserved.
    19.8 + *
    19.9 + * Redistribution and use in source and binary forms, with or without
   19.10 + * modification, are permitted provided that the following conditions are met:
   19.11 + *
   19.12 + *   1. Redistributions of source code must retain the above copyright
   19.13 + *      notice, this list of conditions and the following disclaimer.
   19.14 + *
   19.15 + *   2. Redistributions in binary form must reproduce the above copyright
   19.16 + *      notice, this list of conditions and the following disclaimer in the
   19.17 + *      documentation and/or other materials provided with the distribution.
   19.18 + *
   19.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   19.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   19.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   19.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   19.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   19.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   19.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   19.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   19.29 + * POSSIBILITY OF SUCH DAMAGE.
   19.30 + *
   19.31 + */
   19.32 +package de.uapcore.lightpit.dao.postgres;
   19.33 +
   19.34 +import de.uapcore.lightpit.dao.DataAccessObjects;
   19.35 +import de.uapcore.lightpit.dao.ModuleDao;
   19.36 +import de.uapcore.lightpit.dao.UserDao;
   19.37 +
   19.38 +public class PGDataAccessObjects implements DataAccessObjects {
   19.39 +
   19.40 +    private final ModuleDao moduleDao = new PGModuleDao();
   19.41 +    private final UserDao userDao = new PGUserDao();
   19.42 +
   19.43 +    @Override
   19.44 +    public ModuleDao getModuleDao() {
   19.45 +        return moduleDao;
   19.46 +    }
   19.47 +
   19.48 +    @Override
   19.49 +    public UserDao getUserDao() {
   19.50 +        return userDao;
   19.51 +    }
   19.52 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGModuleDao.java	Sat May 09 17:01:29 2020 +0200
    20.3 @@ -0,0 +1,81 @@
    20.4 +/*
    20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    20.6 + *
    20.7 + * Copyright 2018 Mike Becker. All rights reserved.
    20.8 + *
    20.9 + * Redistribution and use in source and binary forms, with or without
   20.10 + * modification, are permitted provided that the following conditions are met:
   20.11 + *
   20.12 + *   1. Redistributions of source code must retain the above copyright
   20.13 + *      notice, this list of conditions and the following disclaimer.
   20.14 + *
   20.15 + *   2. Redistributions in binary form must reproduce the above copyright
   20.16 + *      notice, this list of conditions and the following disclaimer in the
   20.17 + *      documentation and/or other materials provided with the distribution.
   20.18 + *
   20.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   20.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   20.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   20.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   20.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   20.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   20.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   20.29 + * POSSIBILITY OF SUCH DAMAGE.
   20.30 + *
   20.31 + */
   20.32 +package de.uapcore.lightpit.dao.postgres;
   20.33 +
   20.34 +import de.uapcore.lightpit.LightPITModule;
   20.35 +import de.uapcore.lightpit.dao.AbstractDao;
   20.36 +import de.uapcore.lightpit.dao.ModuleDao;
   20.37 +import de.uapcore.lightpit.entities.Module;
   20.38 +
   20.39 +import java.sql.Connection;
   20.40 +import java.sql.PreparedStatement;
   20.41 +import java.sql.ResultSet;
   20.42 +import java.sql.SQLException;
   20.43 +import java.util.Map;
   20.44 +import java.util.Set;
   20.45 +
   20.46 +public final class PGModuleDao extends AbstractDao<Module> implements ModuleDao {
   20.47 +
   20.48 +    @Override
   20.49 +    protected PreparedStatement listQuery(Connection connection) throws SQLException {
   20.50 +        return connection.prepareStatement("select * from lpitcore_module");
   20.51 +    }
   20.52 +
   20.53 +    @Override
   20.54 +    protected Module mapColumns(ResultSet result) throws SQLException {
   20.55 +        final var mod = new Module();
   20.56 +        mod.setModID(result.getInt("modid"));
   20.57 +        mod.setClassname(result.getString("classname"));
   20.58 +        mod.setVisible(result.getBoolean("visible"));
   20.59 +        mod.setPriority(result.getInt("priority"));
   20.60 +        return mod;
   20.61 +    }
   20.62 +
   20.63 +    @Override
   20.64 +    public void syncRegisteredModuleClasses(Connection conn, Set<Map.Entry<String, LightPITModule>> moduleSet) throws SQLException {
   20.65 +
   20.66 +        var check = conn.prepareStatement("select visible from lpitcore_module where classname = ?");
   20.67 +        var insert = conn.prepareStatement("insert into lpitcore_module (classname, visible, priority) values (?, ?, ?)");
   20.68 +        insert.setBoolean(2, true);
   20.69 +        // update/delete not required, we do this in the module management UI
   20.70 +
   20.71 +        for (Map.Entry<String, LightPITModule> modEntry : moduleSet) {
   20.72 +            if (modEntry.getValue().systemModule()) continue;
   20.73 +
   20.74 +            check.setString(1, modEntry.getKey());
   20.75 +            try (ResultSet r = check.executeQuery()) {
   20.76 +                if (!r.next()) {
   20.77 +                    insert.setString(1, modEntry.getKey());
   20.78 +                    insert.setInt(3, modEntry.getValue().defaultPriority());
   20.79 +                    insert.executeUpdate();
   20.80 +                }
   20.81 +            }
   20.82 +        }
   20.83 +    }
   20.84 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java	Sat May 09 17:01:29 2020 +0200
    21.3 @@ -0,0 +1,56 @@
    21.4 +/*
    21.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    21.6 + *
    21.7 + * Copyright 2018 Mike Becker. All rights reserved.
    21.8 + *
    21.9 + * Redistribution and use in source and binary forms, with or without
   21.10 + * modification, are permitted provided that the following conditions are met:
   21.11 + *
   21.12 + *   1. Redistributions of source code must retain the above copyright
   21.13 + *      notice, this list of conditions and the following disclaimer.
   21.14 + *
   21.15 + *   2. Redistributions in binary form must reproduce the above copyright
   21.16 + *      notice, this list of conditions and the following disclaimer in the
   21.17 + *      documentation and/or other materials provided with the distribution.
   21.18 + *
   21.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   21.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   21.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   21.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   21.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   21.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   21.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   21.29 + * POSSIBILITY OF SUCH DAMAGE.
   21.30 + *
   21.31 + */
   21.32 +package de.uapcore.lightpit.dao.postgres;
   21.33 +
   21.34 +import de.uapcore.lightpit.dao.AbstractDao;
   21.35 +import de.uapcore.lightpit.dao.UserDao;
   21.36 +import de.uapcore.lightpit.entities.User;
   21.37 +
   21.38 +import java.sql.Connection;
   21.39 +import java.sql.PreparedStatement;
   21.40 +import java.sql.ResultSet;
   21.41 +import java.sql.SQLException;
   21.42 +
   21.43 +public final class PGUserDao extends AbstractDao<User> implements UserDao {
   21.44 +
   21.45 +    @Override
   21.46 +    protected User mapColumns(ResultSet result) throws SQLException {
   21.47 +        final var user = new User();
   21.48 +        user.setUserID(result.getInt("userid"));
   21.49 +        user.setUsername(result.getString("username"));
   21.50 +        user.setGivenname(result.getString("givenname"));
   21.51 +        user.setLastname(result.getString("lastname"));
   21.52 +        return user;
   21.53 +    }
   21.54 +
   21.55 +    @Override
   21.56 +    protected PreparedStatement listQuery(Connection conn) throws SQLException {
   21.57 +        return conn.prepareStatement("select * from lpitcore_user where userid >= 0 order by username");
   21.58 +    }
   21.59 +}
    22.1 --- a/src/main/java/de/uapcore/lightpit/entities/Module.java	Sat May 09 15:19:21 2020 +0200
    22.2 +++ b/src/main/java/de/uapcore/lightpit/entities/Module.java	Sat May 09 17:01:29 2020 +0200
    22.3 @@ -1,8 +1,8 @@
    22.4  /*
    22.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    22.6 - * 
    22.7 + *
    22.8   * Copyright 2018 Mike Becker. All rights reserved.
    22.9 - * 
   22.10 + *
   22.11   * Redistribution and use in source and binary forms, with or without
   22.12   * modification, are permitted provided that the following conditions are met:
   22.13   *
    23.1 --- a/src/main/java/de/uapcore/lightpit/modules/ErrorModule.java	Sat May 09 15:19:21 2020 +0200
    23.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ErrorModule.java	Sat May 09 17:01:29 2020 +0200
    23.3 @@ -1,8 +1,8 @@
    23.4  /*
    23.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    23.6 - * 
    23.7 + *
    23.8   * Copyright 2018 Mike Becker. All rights reserved.
    23.9 - * 
   23.10 + *
   23.11   * Redistribution and use in source and binary forms, with or without
   23.12   * modification, are permitted provided that the following conditions are met:
   23.13   *
   23.14 @@ -24,15 +24,12 @@
   23.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   23.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   23.17   * POSSIBILITY OF SUCH DAMAGE.
   23.18 - * 
   23.19 + *
   23.20   */
   23.21  package de.uapcore.lightpit.modules;
   23.22  
   23.23 -import de.uapcore.lightpit.LightPITModule;
   23.24 -import de.uapcore.lightpit.AbstractLightPITServlet;
   23.25 -import de.uapcore.lightpit.HttpMethod;
   23.26 -import de.uapcore.lightpit.RequestMapping;
   23.27 -import de.uapcore.lightpit.ResponseType;
   23.28 +import de.uapcore.lightpit.*;
   23.29 +
   23.30  import javax.servlet.annotation.WebServlet;
   23.31  import javax.servlet.http.HttpServletRequest;
   23.32  import javax.servlet.http.HttpServletResponse;
   23.33 @@ -51,28 +48,28 @@
   23.34          urlPatterns = "/error/*"
   23.35  )
   23.36  public final class ErrorModule extends AbstractLightPITServlet {
   23.37 -    
   23.38 +
   23.39      public static final String REQ_ATTR_ERROR_CODE = "errorCode";
   23.40 -    
   23.41 +
   23.42      private ResponseType handle(HttpServletRequest req, HttpServletResponse resp, int sc) {
   23.43 -        
   23.44 +
   23.45          req.setAttribute(REQ_ATTR_ERROR_CODE, sc);
   23.46          setStylesheet(req, "error");
   23.47          setDynamicFragment(req, "error");
   23.48 -        
   23.49 +
   23.50          return ResponseType.HTML_FULL;
   23.51      }
   23.52 -    
   23.53 +
   23.54      @RequestMapping(requestPath = "404", method = HttpMethod.GET)
   23.55      public ResponseType handle404(HttpServletRequest req, HttpServletResponse resp) {
   23.56          return handle(req, resp, 404);
   23.57      }
   23.58 -    
   23.59 +
   23.60      @RequestMapping(requestPath = "403", method = HttpMethod.GET)
   23.61      public ResponseType handle403(HttpServletRequest req, HttpServletResponse resp) {
   23.62          return handle(req, resp, 403);
   23.63      }
   23.64 -    
   23.65 +
   23.66      @RequestMapping(requestPath = "500", method = HttpMethod.GET)
   23.67      public ResponseType handle500(HttpServletRequest req, HttpServletResponse resp) {
   23.68          return handle(req, resp, 500);
    24.1 --- a/src/main/java/de/uapcore/lightpit/modules/HomeModule.java	Sat May 09 15:19:21 2020 +0200
    24.2 +++ b/src/main/java/de/uapcore/lightpit/modules/HomeModule.java	Sat May 09 17:01:29 2020 +0200
    24.3 @@ -1,8 +1,8 @@
    24.4  /*
    24.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    24.6 - * 
    24.7 + *
    24.8   * Copyright 2018 Mike Becker. All rights reserved.
    24.9 - * 
   24.10 + *
   24.11   * Redistribution and use in source and binary forms, with or without
   24.12   * modification, are permitted provided that the following conditions are met:
   24.13   *
   24.14 @@ -24,7 +24,7 @@
   24.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   24.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   24.17   * POSSIBILITY OF SUCH DAMAGE.
   24.18 - * 
   24.19 + *
   24.20   */
   24.21  package de.uapcore.lightpit.modules;
   24.22  
   24.23 @@ -47,10 +47,10 @@
   24.24          urlPatterns = "/home/*"
   24.25  )
   24.26  public final class HomeModule extends AbstractLightPITServlet {
   24.27 -    
   24.28 +
   24.29      @RequestMapping(method = HttpMethod.GET)
   24.30      public ResponseType handle(HttpServletRequest req, HttpServletResponse resp) {
   24.31 -        
   24.32 +
   24.33          return ResponseType.HTML_FULL;
   24.34      }
   24.35  }
    25.1 --- a/src/main/java/de/uapcore/lightpit/modules/LanguageModule.java	Sat May 09 15:19:21 2020 +0200
    25.2 +++ b/src/main/java/de/uapcore/lightpit/modules/LanguageModule.java	Sat May 09 17:01:29 2020 +0200
    25.3 @@ -1,8 +1,8 @@
    25.4  /*
    25.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    25.6 - * 
    25.7 + *
    25.8   * Copyright 2018 Mike Becker. All rights reserved.
    25.9 - * 
   25.10 + *
   25.11   * Redistribution and use in source and binary forms, with or without
   25.12   * modification, are permitted provided that the following conditions are met:
   25.13   *
   25.14 @@ -24,7 +24,7 @@
   25.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   25.17   * POSSIBILITY OF SUCH DAMAGE.
   25.18 - * 
   25.19 + *
   25.20   */
   25.21  package de.uapcore.lightpit.modules;
   25.22  
   25.23 @@ -49,15 +49,15 @@
   25.24          urlPatterns = "/language/*"
   25.25  )
   25.26  public final class LanguageModule extends AbstractLightPITServlet {
   25.27 -    
   25.28 +
   25.29      private static final Logger LOG = LoggerFactory.getLogger(LanguageModule.class);
   25.30 -    
   25.31 +
   25.32      private final List<Locale> languages = new ArrayList<>();
   25.33  
   25.34      @Override
   25.35      public void init() throws ServletException {
   25.36          super.init();
   25.37 -        
   25.38 +
   25.39          Optional<String[]> langs = Functions.availableLanguages(getServletContext());
   25.40          if (langs.isPresent()) {
   25.41              for (String lang : langs.get()) {
   25.42 @@ -71,7 +71,7 @@
   25.43                      LOG.warn("Specified lanaguge {} in context parameter cannot be mapped to an existing locale - skipping.", lang);
   25.44                  }
   25.45              }
   25.46 -            
   25.47 +
   25.48          } else {
   25.49              languages.add(Locale.ENGLISH);
   25.50              LOG.warn("Context parameter 'available-languges' not found. Only english will be available.");
   25.51 @@ -83,28 +83,28 @@
   25.52          super.destroy();
   25.53          languages.clear();
   25.54      }
   25.55 -    
   25.56 +
   25.57      @RequestMapping(method = HttpMethod.GET)
   25.58      public ResponseType handle(HttpServletRequest req, HttpServletResponse resp) {
   25.59  
   25.60          req.setAttribute("languages", languages);
   25.61          req.setAttribute("browserLanguage", req.getLocale());
   25.62 -        
   25.63 +
   25.64          setStylesheet(req, "language");
   25.65          setDynamicFragment(req, "language");
   25.66          return ResponseType.HTML_FULL;
   25.67      }
   25.68 -    
   25.69 +
   25.70      @RequestMapping(method = HttpMethod.POST)
   25.71      public ResponseType switchLanguage(HttpServletRequest req, HttpServletResponse resp) {
   25.72 -        
   25.73 +
   25.74          Optional<Locale> chosenLanguage = Optional.ofNullable(req.getParameter("language"))
   25.75                  .map(Locale::forLanguageTag)
   25.76                  .filter((l) -> !l.getLanguage().isEmpty());
   25.77 -        
   25.78 +
   25.79          chosenLanguage.ifPresent((l) -> req.getSession().setAttribute(Constants.SESSION_ATTR_LANGUAGE, l));
   25.80          chosenLanguage.ifPresent(resp::setLocale);
   25.81 -        
   25.82 +
   25.83          return handle(req, resp);
   25.84      }
   25.85  }
    26.1 --- a/src/main/java/de/uapcore/lightpit/modules/ModuleManagerModule.java	Sat May 09 15:19:21 2020 +0200
    26.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ModuleManagerModule.java	Sat May 09 17:01:29 2020 +0200
    26.3 @@ -1,8 +1,8 @@
    26.4  /*
    26.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    26.6 - * 
    26.7 + *
    26.8   * Copyright 2018 Mike Becker. All rights reserved.
    26.9 - * 
   26.10 + *
   26.11   * Redistribution and use in source and binary forms, with or without
   26.12   * modification, are permitted provided that the following conditions are met:
   26.13   *
   26.14 @@ -24,13 +24,12 @@
   26.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   26.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   26.17   * POSSIBILITY OF SUCH DAMAGE.
   26.18 - * 
   26.19 + *
   26.20   */
   26.21  package de.uapcore.lightpit.modules;
   26.22  
   26.23  import de.uapcore.lightpit.*;
   26.24  import de.uapcore.lightpit.LightPITModule.ELProxy;
   26.25 -import de.uapcore.lightpit.dao.CoreDAOFactory;
   26.26  import de.uapcore.lightpit.entities.Module;
   26.27  import org.slf4j.Logger;
   26.28  import org.slf4j.LoggerFactory;
   26.29 @@ -59,25 +58,26 @@
   26.30          urlPatterns = "/modmgmt/*"
   26.31  )
   26.32  public final class ModuleManagerModule extends AbstractLightPITServlet {
   26.33 -    
   26.34 +
   26.35      private static final Logger LOG = LoggerFactory.getLogger(ModuleManagerModule.class);
   26.36 -    
   26.37 +
   26.38      private static final String REQ_ATTR_MODULES = "modules";
   26.39 -    
   26.40 -    
   26.41 +
   26.42 +
   26.43      @RequestMapping(method = HttpMethod.GET)
   26.44      public ResponseType handle(HttpServletRequest req, HttpServletResponse resp) throws IOException {
   26.45 -        
   26.46 -        Optional<DataSource> ds = getDatabaseFacade().getDataSource();
   26.47 +
   26.48 +        DatabaseFacade db = getDatabaseFacade();
   26.49 +        Optional<DataSource> ds = db.getDataSource();
   26.50          if (ds.isPresent()) {
   26.51              try (Connection conn = ds.get().getConnection()) {
   26.52 -                final List<Module> modules = CoreDAOFactory.getModuleDao(getDatabaseFacade().getSQLDialect()).listAll(conn);
   26.53 -                
   26.54 +                final List<Module> modules = db.getDataAccessObjects().getModuleDao().list(conn);
   26.55 +
   26.56                  final Map<String, LightPITModule> registeredModules = getModuleManager().getRegisteredModules();
   26.57                  modules.forEach((mod) -> mod.setAnnotatedInfos(ELProxy.convert(registeredModules.get(mod.getClassname()))));
   26.58 -                
   26.59 +
   26.60                  req.setAttribute(REQ_ATTR_MODULES, modules);
   26.61 -                setDynamicFragment(req, "modules");                
   26.62 +                setDynamicFragment(req, "modules");
   26.63                  return ResponseType.HTML_FULL;
   26.64              } catch (SQLException ex) {
   26.65                  LOG.error("Unexpected SQL Exception", ex);
    27.1 --- a/src/main/java/de/uapcore/lightpit/modules/VersionsModule.java	Sat May 09 15:19:21 2020 +0200
    27.2 +++ b/src/main/java/de/uapcore/lightpit/modules/VersionsModule.java	Sat May 09 17:01:29 2020 +0200
    27.3 @@ -1,8 +1,8 @@
    27.4  /*
    27.5   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    27.6 - * 
    27.7 + *
    27.8   * Copyright 2018 Mike Becker. All rights reserved.
    27.9 - * 
   27.10 + *
   27.11   * Redistribution and use in source and binary forms, with or without
   27.12   * modification, are permitted provided that the following conditions are met:
   27.13   *
   27.14 @@ -24,15 +24,12 @@
   27.15   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   27.16   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   27.17   * POSSIBILITY OF SUCH DAMAGE.
   27.18 - * 
   27.19 + *
   27.20   */
   27.21  package de.uapcore.lightpit.modules;
   27.22  
   27.23 -import de.uapcore.lightpit.LightPITModule;
   27.24 -import de.uapcore.lightpit.AbstractLightPITServlet;
   27.25 -import de.uapcore.lightpit.HttpMethod;
   27.26 -import de.uapcore.lightpit.RequestMapping;
   27.27 -import de.uapcore.lightpit.ResponseType;
   27.28 +import de.uapcore.lightpit.*;
   27.29 +
   27.30  import javax.servlet.annotation.WebServlet;
   27.31  import javax.servlet.http.HttpServletRequest;
   27.32  import javax.servlet.http.HttpServletResponse;
   27.33 @@ -49,7 +46,7 @@
   27.34  public final class VersionsModule extends AbstractLightPITServlet {
   27.35      @RequestMapping(method = HttpMethod.GET)
   27.36      public ResponseType handle(HttpServletRequest req, HttpServletResponse resp) {
   27.37 -        
   27.38 +
   27.39          return ResponseType.HTML_FULL;
   27.40      }
   27.41  }

mercurial