--- a/src/main/java/de/uapcore/lightpit/ModuleManager.java Sun May 10 10:11:10 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/ModuleManager.java Sun May 10 10:11:37 2020 +0200 @@ -28,7 +28,6 @@ */ package de.uapcore.lightpit; -import de.uapcore.lightpit.entities.Module; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,11 +36,7 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; -import java.sql.Connection; -import java.sql.SQLException; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; /** * Scans registered servlets for LightPIT modules. @@ -63,9 +58,9 @@ private final Map<String, LightPITModule> registeredModules = new HashMap<>(); /** - * This flag is true, when synchronization is needed. + * Contains the menu entries for the loaded modules. */ - private final AtomicBoolean dirty = new AtomicBoolean(true); + private final List<MenuEntry> mainMenu = new ArrayList<>(); @Override public void contextInitialized(ServletContextEvent sce) { @@ -132,41 +127,9 @@ public void reloadAll() { registeredModules.clear(); sc.getServletRegistrations().forEach(this::handleServletRegistration); - - // TODO: implement dependency resolver - - dirty.set(true); - LOG.info("Modules loaded."); - } + createMainMenu(); - /** - * Synchronizes module information with the database. - * <p> - * This must be called from the {@link AbstractLightPITServlet}. - * Admittedly the call will perform the synchronization once after reload - * and be a no-op, afterwards. - * However, since the DatabaseFacade might be loaded after the module - * manager, we must defer the synchronization to the first request - * handled by the Servlet. - * - * @param db interface to the database - */ - public void syncWithDatabase(DatabaseFacade db) { - if (dirty.compareAndSet(true, false)) { - if (db.getDataSource().isPresent()) { - try (Connection conn = db.getDataSource().get().getConnection()) { - db.getDataAccessObjects() - .getModuleDao() - .syncRegisteredModuleClasses(conn, registeredModules.entrySet()); - } catch (SQLException ex) { - LOG.error("Unexpected SQL Exception", ex); - } - } else { - LOG.error("No datasource present. Cannot sync module information with database."); - } - } else { - LOG.trace("Module information clean - no synchronization required."); - } + LOG.info("Modules loaded."); } /** @@ -178,46 +141,30 @@ } /** - * Returns the main menu. - * - * @param db the interface to the database - * @return a list of menus belonging to the main menu + * Populates the main menu based on the registered modules. */ - public List<Menu> getMainMenu(DatabaseFacade db) { - // TODO: user specific menu - - if (db.getDataSource().isPresent()) { - try (Connection conn = db.getDataSource().get().getConnection()) { - final List<Module> modules = db.getDataAccessObjects().getModuleDao().list(conn); - - return modules - .stream() - .filter(Module::isVisible) - .sorted(new Module.PriorityComparator()) - .map(mod -> new Menu( - mod.getClassname(), - new ResourceKey( - registeredModules.get(mod.getClassname()).bundleBaseName(), - registeredModules.get(mod.getClassname()).menuKey()), - registeredModules.get(mod.getClassname()).modulePath())) - .collect(Collectors.toList()); - } catch (SQLException ex) { - LOG.error("Unexpected SQLException when loading the main menu", ex); - return Collections.emptyList(); - } - } else { - return Collections.emptyList(); - } + private void createMainMenu() { + mainMenu.clear(); + registeredModules.entrySet() + .stream() + .filter(mod -> !mod.getValue().systemModule()) + .map(mod -> new MenuEntry( + mod.getKey(), + new ResourceKey( + mod.getValue().bundleBaseName(), + mod.getValue().menuKey()), + mod.getValue().modulePath(), + mod.getValue().defaultPriority())) + .sorted() + .forEachOrdered(mainMenu::add); } /** - * Returns an unmodifiable map of all registered modules. - * <p> - * The key is the classname of the module. + * Returns the main menu. * - * @return the map of registered modules + * @return a list of menu items */ - public Map<String, LightPITModule> getRegisteredModules() { - return Collections.unmodifiableMap(registeredModules); + public List<MenuEntry> getMainMenu() { + return Collections.unmodifiableList(mainMenu); } }