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