26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 * |
27 * |
28 */ |
28 */ |
29 package de.uapcore.lightpit; |
29 package de.uapcore.lightpit; |
30 |
30 |
|
31 import java.util.ArrayList; |
|
32 import java.util.Collections; |
|
33 import java.util.List; |
|
34 import java.util.Optional; |
31 import javax.servlet.Registration; |
35 import javax.servlet.Registration; |
32 import javax.servlet.ServletContext; |
36 import javax.servlet.ServletContext; |
33 import javax.servlet.ServletContextEvent; |
37 import javax.servlet.ServletContextEvent; |
34 import javax.servlet.ServletContextListener; |
38 import javax.servlet.ServletContextListener; |
35 import javax.servlet.annotation.WebListener; |
39 import javax.servlet.annotation.WebListener; |
38 |
42 |
39 /** |
43 /** |
40 * Scans registered servlets for LightPIT modules. |
44 * Scans registered servlets for LightPIT modules. |
41 */ |
45 */ |
42 @WebListener |
46 @WebListener |
43 public class ModuleManager implements ServletContextListener { |
47 public final class ModuleManager implements ServletContextListener { |
44 |
48 |
45 private static final Logger LOG = LoggerFactory.getLogger(ModuleManager.class); |
49 private static final Logger LOG = LoggerFactory.getLogger(ModuleManager.class); |
46 |
50 |
47 /** |
51 /** |
48 * The attribute name in the servlet context under which an instance of this class can be found. |
52 * The attribute name in the servlet context under which an instance of this class can be found. |
49 */ |
53 */ |
50 public static final String SC_ATTR_NAME = ModuleManager.class.getName(); |
54 public static final String SC_ATTR_NAME = ModuleManager.class.getName(); |
|
55 private ServletContext sc; |
51 |
56 |
52 private ServletContext sc; |
57 private final List<Menu> mainMenu = new ArrayList<>(); |
|
58 private final List<Menu> immutableMainMenu = Collections.unmodifiableList(mainMenu); |
53 |
59 |
54 @Override |
60 @Override |
55 public void contextInitialized(ServletContextEvent sce) { |
61 public void contextInitialized(ServletContextEvent sce) { |
56 sc = sce.getServletContext(); |
62 sc = sce.getServletContext(); |
57 reloadAll(); |
63 reloadAll(); |
59 LOG.info("Module manager injected into ServletContext."); |
65 LOG.info("Module manager injected into ServletContext."); |
60 } |
66 } |
61 |
67 |
62 @Override |
68 @Override |
63 public void contextDestroyed(ServletContextEvent sce) { |
69 public void contextDestroyed(ServletContextEvent sce) { |
64 assert sc != null && sc.equals(sce.getServletContext()); |
|
65 sc.removeAttribute(SC_ATTR_NAME); |
|
66 unloadAll(); |
70 unloadAll(); |
67 } |
71 } |
68 |
72 |
69 private boolean isRegisteredAsModule(Registration reg) { |
73 private Optional<LightPITModule> getModuleInfo(Registration reg) { |
70 try { |
74 try { |
71 final Class scclass = Class.forName(reg.getClassName()); |
75 final Class scclass = Class.forName(reg.getClassName()); |
72 |
76 |
73 final boolean lpservlet = AbstractLightPITServlet.class.isAssignableFrom(scclass); |
77 final boolean lpservlet = AbstractLightPITServlet.class.isAssignableFrom(scclass); |
74 final boolean lpmodule = scclass.isAnnotationPresent(LightPITModule.class); |
78 final boolean lpmodule = scclass.isAnnotationPresent(LightPITModule.class); |
84 reg.getClassName(), |
88 reg.getClassName(), |
85 AbstractLightPITServlet.class.getSimpleName() |
89 AbstractLightPITServlet.class.getSimpleName() |
86 ); |
90 ); |
87 } |
91 } |
88 |
92 |
89 return lpservlet && lpmodule; |
93 if (lpservlet && lpmodule) { |
|
94 final Class<? extends AbstractLightPITServlet> clazz = scclass; |
|
95 final LightPITModule moduleInfo = clazz.getAnnotation(LightPITModule.class); |
|
96 return Optional.of(moduleInfo); |
|
97 } else { |
|
98 return Optional.empty(); |
|
99 } |
90 } catch (ClassNotFoundException ex) { |
100 } catch (ClassNotFoundException ex) { |
91 LOG.error( |
101 LOG.error( |
92 "Servlet registration refers to class {} which cannot be found by the class loader (Reason: {})", |
102 "Servlet registration refers to class {} which cannot be found by the class loader (Reason: {})", |
93 reg.getClassName(), |
103 reg.getClassName(), |
94 ex.getMessage() |
104 ex.getMessage() |
95 ); |
105 ); |
96 return false; |
106 return Optional.empty(); |
97 } |
107 } |
98 } |
108 } |
99 |
109 |
|
110 private void addModuleToMenu(LightPITModule moduleInfo) { |
|
111 final Menu menu = new Menu( |
|
112 new ResourceKey(moduleInfo.bundleBaseName(), moduleInfo.menuKey()), |
|
113 moduleInfo.modulePath() |
|
114 ); |
|
115 mainMenu.add(menu); |
|
116 } |
|
117 |
100 private void handleServletRegistration(String name, Registration reg) { |
118 private void handleServletRegistration(String name, Registration reg) { |
101 if (isRegisteredAsModule(reg)) { |
119 final Optional<LightPITModule> moduleInfo = getModuleInfo(reg); |
|
120 if (moduleInfo.isPresent()) { |
|
121 addModuleToMenu(moduleInfo.get()); |
|
122 |
102 LOG.info("Module detected: {}", name); |
123 LOG.info("Module detected: {}", name); |
103 } else { |
124 } else { |
104 LOG.debug("Servlet {} is no module, skipping.", name); |
125 LOG.debug("Servlet {} is no module, skipping.", name); |
105 } |
126 } |
106 } |
127 } |