Sat, 09 May 2020 17:01:29 +0200
cleanup and simplification of database access layer
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 }