1.1 --- a/src/main/java/de/uapcore/lightpit/ModuleManager.java Sun May 10 10:11:10 2020 +0200 1.2 +++ b/src/main/java/de/uapcore/lightpit/ModuleManager.java Sun May 10 10:11:37 2020 +0200 1.3 @@ -28,7 +28,6 @@ 1.4 */ 1.5 package de.uapcore.lightpit; 1.6 1.7 -import de.uapcore.lightpit.entities.Module; 1.8 import org.slf4j.Logger; 1.9 import org.slf4j.LoggerFactory; 1.10 1.11 @@ -37,11 +36,7 @@ 1.12 import javax.servlet.ServletContextEvent; 1.13 import javax.servlet.ServletContextListener; 1.14 import javax.servlet.annotation.WebListener; 1.15 -import java.sql.Connection; 1.16 -import java.sql.SQLException; 1.17 import java.util.*; 1.18 -import java.util.concurrent.atomic.AtomicBoolean; 1.19 -import java.util.stream.Collectors; 1.20 1.21 /** 1.22 * Scans registered servlets for LightPIT modules. 1.23 @@ -63,9 +58,9 @@ 1.24 private final Map<String, LightPITModule> registeredModules = new HashMap<>(); 1.25 1.26 /** 1.27 - * This flag is true, when synchronization is needed. 1.28 + * Contains the menu entries for the loaded modules. 1.29 */ 1.30 - private final AtomicBoolean dirty = new AtomicBoolean(true); 1.31 + private final List<MenuEntry> mainMenu = new ArrayList<>(); 1.32 1.33 @Override 1.34 public void contextInitialized(ServletContextEvent sce) { 1.35 @@ -132,44 +127,12 @@ 1.36 public void reloadAll() { 1.37 registeredModules.clear(); 1.38 sc.getServletRegistrations().forEach(this::handleServletRegistration); 1.39 + createMainMenu(); 1.40 1.41 - // TODO: implement dependency resolver 1.42 - 1.43 - dirty.set(true); 1.44 LOG.info("Modules loaded."); 1.45 } 1.46 1.47 /** 1.48 - * Synchronizes module information with the database. 1.49 - * <p> 1.50 - * This must be called from the {@link AbstractLightPITServlet}. 1.51 - * Admittedly the call will perform the synchronization once after reload 1.52 - * and be a no-op, afterwards. 1.53 - * However, since the DatabaseFacade might be loaded after the module 1.54 - * manager, we must defer the synchronization to the first request 1.55 - * handled by the Servlet. 1.56 - * 1.57 - * @param db interface to the database 1.58 - */ 1.59 - public void syncWithDatabase(DatabaseFacade db) { 1.60 - if (dirty.compareAndSet(true, false)) { 1.61 - if (db.getDataSource().isPresent()) { 1.62 - try (Connection conn = db.getDataSource().get().getConnection()) { 1.63 - db.getDataAccessObjects() 1.64 - .getModuleDao() 1.65 - .syncRegisteredModuleClasses(conn, registeredModules.entrySet()); 1.66 - } catch (SQLException ex) { 1.67 - LOG.error("Unexpected SQL Exception", ex); 1.68 - } 1.69 - } else { 1.70 - LOG.error("No datasource present. Cannot sync module information with database."); 1.71 - } 1.72 - } else { 1.73 - LOG.trace("Module information clean - no synchronization required."); 1.74 - } 1.75 - } 1.76 - 1.77 - /** 1.78 * Unloads all found modules. 1.79 */ 1.80 public void unloadAll() { 1.81 @@ -178,46 +141,30 @@ 1.82 } 1.83 1.84 /** 1.85 - * Returns the main menu. 1.86 - * 1.87 - * @param db the interface to the database 1.88 - * @return a list of menus belonging to the main menu 1.89 + * Populates the main menu based on the registered modules. 1.90 */ 1.91 - public List<Menu> getMainMenu(DatabaseFacade db) { 1.92 - // TODO: user specific menu 1.93 - 1.94 - if (db.getDataSource().isPresent()) { 1.95 - try (Connection conn = db.getDataSource().get().getConnection()) { 1.96 - final List<Module> modules = db.getDataAccessObjects().getModuleDao().list(conn); 1.97 - 1.98 - return modules 1.99 - .stream() 1.100 - .filter(Module::isVisible) 1.101 - .sorted(new Module.PriorityComparator()) 1.102 - .map(mod -> new Menu( 1.103 - mod.getClassname(), 1.104 - new ResourceKey( 1.105 - registeredModules.get(mod.getClassname()).bundleBaseName(), 1.106 - registeredModules.get(mod.getClassname()).menuKey()), 1.107 - registeredModules.get(mod.getClassname()).modulePath())) 1.108 - .collect(Collectors.toList()); 1.109 - } catch (SQLException ex) { 1.110 - LOG.error("Unexpected SQLException when loading the main menu", ex); 1.111 - return Collections.emptyList(); 1.112 - } 1.113 - } else { 1.114 - return Collections.emptyList(); 1.115 - } 1.116 + private void createMainMenu() { 1.117 + mainMenu.clear(); 1.118 + registeredModules.entrySet() 1.119 + .stream() 1.120 + .filter(mod -> !mod.getValue().systemModule()) 1.121 + .map(mod -> new MenuEntry( 1.122 + mod.getKey(), 1.123 + new ResourceKey( 1.124 + mod.getValue().bundleBaseName(), 1.125 + mod.getValue().menuKey()), 1.126 + mod.getValue().modulePath(), 1.127 + mod.getValue().defaultPriority())) 1.128 + .sorted() 1.129 + .forEachOrdered(mainMenu::add); 1.130 } 1.131 1.132 /** 1.133 - * Returns an unmodifiable map of all registered modules. 1.134 - * <p> 1.135 - * The key is the classname of the module. 1.136 + * Returns the main menu. 1.137 * 1.138 - * @return the map of registered modules 1.139 + * @return a list of menu items 1.140 */ 1.141 - public Map<String, LightPITModule> getRegisteredModules() { 1.142 - return Collections.unmodifiableMap(registeredModules); 1.143 + public List<MenuEntry> getMainMenu() { 1.144 + return Collections.unmodifiableList(mainMenu); 1.145 } 1.146 }