src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java

changeset 33
fd8c40ff78c3
parent 29
27a0fdd7bca7
child 34
824d4042c857
equal deleted inserted replaced
32:63a31871189e 33:fd8c40ff78c3
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.io.IOException; 31 import org.slf4j.Logger;
32 import java.lang.reflect.Method; 32 import org.slf4j.LoggerFactory;
33 import java.lang.reflect.Modifier; 33
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.Optional;
40 import javax.servlet.ServletException; 34 import javax.servlet.ServletException;
41 import javax.servlet.http.HttpServlet; 35 import javax.servlet.http.HttpServlet;
42 import javax.servlet.http.HttpServletRequest; 36 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse; 37 import javax.servlet.http.HttpServletResponse;
44 import javax.servlet.http.HttpSession; 38 import javax.servlet.http.HttpSession;
45 import org.slf4j.Logger; 39 import java.io.IOException;
46 import org.slf4j.LoggerFactory; 40 import java.lang.reflect.Method;
41 import java.lang.reflect.Modifier;
42 import java.util.*;
47 43
48 /** 44 /**
49 * A special implementation of a HTTPServlet which is focused on implementing 45 * A special implementation of a HTTPServlet which is focused on implementing
50 * the necessary functionality for {@link LightPITModule}s. 46 * the necessary functionality for {@link LightPITModule}s.
51 */ 47 */
52 public abstract class AbstractLightPITServlet extends HttpServlet { 48 public abstract class AbstractLightPITServlet extends HttpServlet {
53 49
54 private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class); 50 private static final Logger LOG = LoggerFactory.getLogger(AbstractLightPITServlet.class);
55 51
56 private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full"); 52 private static final String HTML_FULL_DISPATCHER = Functions.jspPath("html_full");
57 53
58 /** 54 /**
59 * Store a reference to the annotation for quicker access. 55 * Store a reference to the annotation for quicker access.
60 */ 56 */
61 private Optional<LightPITModule> moduleInfo = Optional.empty(); 57 private LightPITModule moduleInfo = null;
62 58
63 /** 59 /**
64 * The EL proxy is necessary, because the EL resolver cannot handle annotation properties. 60 * The EL proxy is necessary, because the EL resolver cannot handle annotation properties.
65 */ 61 */
66 private Optional<LightPITModule.ELProxy> moduleInfoELProxy = Optional.empty(); 62 private LightPITModule.ELProxy moduleInfoELProxy = null;
67 63
68 64
69 @FunctionalInterface 65 @FunctionalInterface
70 private static interface HandlerMethod { 66 private interface HandlerMethod {
71 ResponseType apply(HttpServletRequest t, HttpServletResponse u) throws IOException, ServletException; 67 ResponseType apply(HttpServletRequest t, HttpServletResponse u) throws IOException;
72 } 68 }
73 69
74 /** 70 /**
75 * Invocation mapping gathered from the {@link RequestMapping} annotations. 71 * Invocation mapping gathered from the {@link RequestMapping} annotations.
76 * 72 *
82 */ 78 */
83 private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>(); 79 private final Map<HttpMethod, Map<String, HandlerMethod>> mappings = new HashMap<>();
84 80
85 /** 81 /**
86 * Gives implementing modules access to the {@link ModuleManager}. 82 * Gives implementing modules access to the {@link ModuleManager}.
83 *
87 * @return the module manager 84 * @return the module manager
88 */ 85 */
89 protected final ModuleManager getModuleManager() { 86 protected final ModuleManager getModuleManager() {
90 return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME); 87 return (ModuleManager) getServletContext().getAttribute(ModuleManager.SC_ATTR_NAME);
91 } 88 }
92 89
90 public final LightPITModule getModuleInfo() {
91 return moduleInfo;
92 }
93
93 /** 94 /**
94 * Gives implementing modules access to the {@link DatabaseFacade}. 95 * Gives implementing modules access to the {@link DatabaseFacade}.
96 *
95 * @return the database facade 97 * @return the database facade
96 */ 98 */
97 protected final DatabaseFacade getDatabaseFacade() { 99 protected final DatabaseFacade getDatabaseFacade() {
98 return (DatabaseFacade) getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME); 100 return (DatabaseFacade) getServletContext().getAttribute(DatabaseFacade.SC_ATTR_NAME);
99 } 101 }
100 102
101 private ResponseType invokeMapping(Method method, HttpServletRequest req, HttpServletResponse resp) 103 private ResponseType invokeMapping(Method method, HttpServletRequest req, HttpServletResponse resp) throws IOException {
102 throws IOException, ServletException {
103 try { 104 try {
104 LOG.trace("invoke {}#{}", method.getDeclaringClass().getName(), method.getName()); 105 LOG.trace("invoke {}#{}", method.getDeclaringClass().getName(), method.getName());
105 return (ResponseType) method.invoke(this, req, resp); 106 return (ResponseType) method.invoke(this, req, resp);
106 } catch (ReflectiveOperationException | ClassCastException ex) { 107 } catch (ReflectiveOperationException | ClassCastException ex) {
107 LOG.error(String.format("invocation of method %s failed", method.getName()), ex); 108 LOG.error(String.format("invocation of method %s failed", method.getName()), ex);
110 } 111 }
111 } 112 }
112 113
113 @Override 114 @Override
114 public void init() throws ServletException { 115 public void init() throws ServletException {
115 moduleInfo = Optional.ofNullable(this.getClass().getAnnotation(LightPITModule.class)); 116 moduleInfo = this.getClass().getAnnotation(LightPITModule.class);
116 moduleInfoELProxy = moduleInfo.map(LightPITModule.ELProxy::convert); 117 moduleInfoELProxy = moduleInfo == null ? null : LightPITModule.ELProxy.convert(moduleInfo);
117 118
118 if (moduleInfo.isPresent()) { 119 if (moduleInfo != null) {
119 scanForRequestMappings(); 120 scanForRequestMappings();
120 } 121 }
121 122
122 LOG.trace("{} initialized", getServletName()); 123 LOG.trace("{} initialized", getServletName());
123 } 124 }
124 125
125 private void scanForRequestMappings() { 126 private void scanForRequestMappings() {
126 try { 127 try {
268 } 269 }
269 270
270 // set some internal request attributes 271 // set some internal request attributes
271 req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req)); 272 req.setAttribute(Constants.REQ_ATTR_PATH, Functions.fullPath(req));
272 req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName()); 273 req.setAttribute(Constants.REQ_ATTR_MODULE_CLASSNAME, this.getClass().getName());
273 moduleInfoELProxy.ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy)); 274 Optional.ofNullable(moduleInfoELProxy).ifPresent((proxy) -> req.setAttribute(Constants.REQ_ATTR_MODULE_INFO, proxy));
274 275
275 276
276 // call the handler, if available, or send an HTTP 404 error 277 // call the handler, if available, or send an HTTP 404 error
277 Optional<HandlerMethod> mapping = findMapping(method, req); 278 Optional<HandlerMethod> mapping = findMapping(method, req);
278 if (mapping.isPresent()) { 279 if (mapping.isPresent()) {

mercurial