]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.lib.equinox/src/org/argeo/cms/equinox/http/jetty/EquinoxJettyServer.java
Improve events and web sockets
[lgpl/argeo-commons.git] / org.argeo.cms.lib.equinox / src / org / argeo / cms / equinox / http / jetty / EquinoxJettyServer.java
1 package org.argeo.cms.equinox.http.jetty;
2
3 import java.io.IOException;
4 import java.lang.reflect.InvocationTargetException;
5 import java.lang.reflect.Method;
6
7 import javax.servlet.Servlet;
8 import javax.servlet.ServletConfig;
9 import javax.servlet.ServletContext;
10 import javax.servlet.ServletException;
11 import javax.servlet.ServletRequest;
12 import javax.servlet.ServletResponse;
13 import javax.servlet.http.HttpSessionEvent;
14 import javax.servlet.http.HttpSessionIdListener;
15 import javax.servlet.http.HttpSessionListener;
16
17 import org.argeo.cms.jetty.CmsJettyServer;
18 import org.eclipse.equinox.http.servlet.HttpServiceServlet;
19 import org.eclipse.jetty.server.session.SessionHandler;
20 import org.eclipse.jetty.servlet.ServletContextHandler;
21 import org.eclipse.jetty.servlet.ServletHolder;
22 import org.osgi.framework.Constants;
23
24 public class EquinoxJettyServer extends CmsJettyServer {
25 private static final String INTERNAL_CONTEXT_CLASSLOADER = "org.eclipse.equinox.http.jetty.internal.ContextClassLoader";
26
27 @Override
28 protected void addServlets(ServletContextHandler rootContextHandler) throws ServletException {
29 ServletHolder holder = new ServletHolder(new InternalHttpServiceServlet());
30 holder.setInitOrder(0);
31 holder.setInitParameter(Constants.SERVICE_VENDOR, "Eclipse.org"); //$NON-NLS-1$
32 holder.setInitParameter(Constants.SERVICE_DESCRIPTION, "Equinox Jetty-based Http Service"); //$NON-NLS-1$
33
34 // holder.setInitParameter(JettyConstants.CONTEXT_PATH,
35 // httpContext.getContextPath());
36 rootContextHandler.addServlet(holder, "/*");
37
38 // post-start
39 SessionHandler sessionManager = rootContextHandler.getSessionHandler();
40 sessionManager.addEventListener((HttpSessionIdListener) holder.getServlet());
41 }
42
43 public static class InternalHttpServiceServlet implements HttpSessionListener, HttpSessionIdListener, Servlet {
44 private final Servlet httpServiceServlet = new HttpServiceServlet();
45 private ClassLoader contextLoader;
46 private final Method sessionDestroyed;
47 private final Method sessionIdChanged;
48
49 public InternalHttpServiceServlet() {
50 Class<?> clazz = httpServiceServlet.getClass();
51
52 try {
53 sessionDestroyed = clazz.getMethod("sessionDestroyed", new Class<?>[] { String.class }); //$NON-NLS-1$
54 } catch (Exception e) {
55 throw new IllegalStateException(e);
56 }
57 try {
58 sessionIdChanged = clazz.getMethod("sessionIdChanged", new Class<?>[] { String.class }); //$NON-NLS-1$
59 } catch (Exception e) {
60 throw new IllegalStateException(e);
61 }
62 }
63
64 @Override
65 public void init(ServletConfig config) throws ServletException {
66 ServletContext context = config.getServletContext();
67 contextLoader = (ClassLoader) context.getAttribute(INTERNAL_CONTEXT_CLASSLOADER);
68
69 Thread thread = Thread.currentThread();
70 ClassLoader current = thread.getContextClassLoader();
71 thread.setContextClassLoader(contextLoader);
72 try {
73 httpServiceServlet.init(config);
74 } finally {
75 thread.setContextClassLoader(current);
76 }
77 }
78
79 @Override
80 public void destroy() {
81 Thread thread = Thread.currentThread();
82 ClassLoader current = thread.getContextClassLoader();
83 thread.setContextClassLoader(contextLoader);
84 try {
85 httpServiceServlet.destroy();
86 } finally {
87 thread.setContextClassLoader(current);
88 }
89 contextLoader = null;
90 }
91
92 @Override
93 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
94 Thread thread = Thread.currentThread();
95 ClassLoader current = thread.getContextClassLoader();
96 thread.setContextClassLoader(contextLoader);
97 try {
98 httpServiceServlet.service(req, res);
99 } finally {
100 thread.setContextClassLoader(current);
101 }
102 }
103
104 @Override
105 public ServletConfig getServletConfig() {
106 return httpServiceServlet.getServletConfig();
107 }
108
109 @Override
110 public String getServletInfo() {
111 return httpServiceServlet.getServletInfo();
112 }
113
114 @Override
115 public void sessionCreated(HttpSessionEvent event) {
116 // Nothing to do.
117 }
118
119 @Override
120 public void sessionDestroyed(HttpSessionEvent event) {
121 Thread thread = Thread.currentThread();
122 ClassLoader current = thread.getContextClassLoader();
123 thread.setContextClassLoader(contextLoader);
124 try {
125 sessionDestroyed.invoke(httpServiceServlet, event.getSession().getId());
126 } catch (IllegalAccessException | IllegalArgumentException e) {
127 // not likely
128 } catch (InvocationTargetException e) {
129 throw new RuntimeException(e.getCause());
130 } finally {
131 thread.setContextClassLoader(current);
132 }
133 }
134
135 @Override
136 public void sessionIdChanged(HttpSessionEvent event, String oldSessionId) {
137 Thread thread = Thread.currentThread();
138 ClassLoader current = thread.getContextClassLoader();
139 thread.setContextClassLoader(contextLoader);
140 try {
141 sessionIdChanged.invoke(httpServiceServlet, oldSessionId);
142 } catch (IllegalAccessException | IllegalArgumentException e) {
143 // not likely
144 } catch (InvocationTargetException e) {
145 throw new RuntimeException(e.getCause());
146 } finally {
147 thread.setContextClassLoader(current);
148 }
149 }
150 }
151
152 }