src/java/de/uapcore/lightpit/ModuleManager.java

changeset 27
1f2a96efa69f
parent 24
8137ec335416
--- a/src/java/de/uapcore/lightpit/ModuleManager.java	Sun Apr 08 15:34:11 2018 +0200
+++ b/src/java/de/uapcore/lightpit/ModuleManager.java	Sun Apr 08 16:41:02 2018 +0200
@@ -29,6 +29,7 @@
 package de.uapcore.lightpit;
 
 import de.uapcore.lightpit.entities.CoreDAOFactory;
+import de.uapcore.lightpit.entities.Module;
 import de.uapcore.lightpit.entities.ModuleDao;
 import java.sql.Connection;
 import java.sql.SQLException;
@@ -36,9 +37,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Optional;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 import javax.servlet.Registration;
@@ -64,18 +63,15 @@
     private ServletContext sc;
     
     /**
+     * Maps class names to module information.
+     */
+    private final Map<String, LightPITModule> registeredModules = new HashMap<>();
+    
+    /**
      * This flag is true, when synchronization is needed.
      */
     private final AtomicBoolean dirty = new AtomicBoolean(true);
     
-    private final CopyOnWriteArrayList<Menu> mainMenu = new CopyOnWriteArrayList<>();
-    private final List<Menu> immutableMainMenu = Collections.unmodifiableList(mainMenu);
-    
-    /**
-     * Maps class names to module information.
-     */
-    private final Map<String, LightPITModule> registeredModules = new HashMap<>();
-    
     @Override
     public void contextInitialized(ServletContextEvent sce) {
         sc = sce.getServletContext();
@@ -152,6 +148,13 @@
     /**
      * Synchronizes module information with the database.
      * 
+     * 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, we 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) {
@@ -159,27 +162,12 @@
             if (db.getDataSource().isPresent()) {
                 try (Connection conn = db.getDataSource().get().getConnection()) {
                     final ModuleDao moduleDao = CoreDAOFactory.getModuleDao(db.getSQLDialect());
-                    
-                    final List<Entry<String, LightPITModule>> visibleModules =
-                            moduleDao.syncRegisteredModuleClasses(conn, registeredModules.entrySet());
-                    
-                    final List<Menu> updatedMenu = visibleModules
-                            .stream()
-                            .collect(Collectors.mapping(
-                                    (mod) -> new Menu(
-                                            mod.getKey(),
-                                            new ResourceKey(mod.getValue().bundleBaseName(), mod.getValue().menuKey()),
-                                            mod.getValue().modulePath()),
-                                    Collectors.toList())
-                            );
-                    
-                    mainMenu.removeIf((e) -> !updatedMenu.contains(e));
-                    mainMenu.addAllAbsent(updatedMenu);
+                    moduleDao.syncRegisteredModuleClasses(conn, registeredModules.entrySet());
                 } catch (SQLException ex) {
                     LOG.error("Unexpected SQL Exception", ex);
                 }
             } else {
-                LOG.warn("No datasource present. Cannot sync module information with database.");
+                LOG.error("No datasource present. Cannot sync module information with database.");
             }
         } else {
             LOG.trace("Module information clean - no synchronization required.");
@@ -190,17 +178,44 @@
      * Unloads all found modules.
      */
     public void unloadAll() {
-        mainMenu.clear();
         registeredModules.clear();
         LOG.info("All modules unloaded.");
     }
 
     /**
      * Returns the main menu.
+     * 
+     * @param db the interface to the database
      * @return a list of menus belonging to the main menu
      */
-    public List<Menu> getMainMenu() {
-        return immutableMainMenu;
+    public List<Menu> getMainMenu(DatabaseFacade db) {
+        // TODO: user specific menu
+        
+        if (db.getDataSource().isPresent()) {
+            try (Connection conn = db.getDataSource().get().getConnection()) {
+                final ModuleDao dao = CoreDAOFactory.getModuleDao(db.getSQLDialect());
+                final List<Module> modules = dao.listAll(conn);
+                
+                final List<Menu> menu = modules
+                    .stream()
+                    .filter((mod) -> mod.isVisible())
+                    .collect(Collectors.mapping(
+                            (mod) -> new Menu(
+                                    mod.getClassname(),
+                                    new ResourceKey(
+                                            registeredModules.get(mod.getClassname()).bundleBaseName(),
+                                            registeredModules.get(mod.getClassname()).menuKey()),
+                                    registeredModules.get(mod.getClassname()).modulePath()),
+                            Collectors.toList())
+                    );
+                return menu;
+            } catch (SQLException ex) {
+                LOG.error("Unexpected SQLException when loading the main menu", ex);
+                return Collections.emptyList();
+            }
+        } else {
+            return Collections.emptyList();
+        }
     }
     
     /**

mercurial