1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.osgi.nested;
14
15 import java.lang.reflect.Method;
16
17 import javax.servlet.http.HttpServlet;
18
19 import org.eclipse.jetty.nested.NestedConnector;
20 import org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener;
21 import org.eclipse.jetty.util.component.LifeCycle;
22 import org.osgi.framework.FrameworkUtil;
23
24
25
26
27
28
29
30
31
32 public class NestedConnectorListener extends AbstractLifeCycleListener
33 {
34
35
36 private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet";
37
38
39
40 private String registerServletDelegateMethodName = "registerServletDelegate";
41
42
43
44 private String unregisterServletDelegateMethodName = "unregisterServletDelegate";
45
46
47 private NestedConnectorServletDelegate _servletDelegate;
48
49
50
51
52 private NestedConnector nestedConnector;
53
54
55
56
57
58 public void setBridgeServletClassName(String bridgeServletClassName)
59 {
60 this.bridgeServletClassName = bridgeServletClassName;
61 }
62
63 public String getBridgeServletClassName()
64 {
65 return this.bridgeServletClassName;
66 }
67 public String getRegisterServletDelegateMethodName()
68 {
69 return this.registerServletDelegateMethodName;
70 }
71 public String getUnregisterServletDelegateMethodName()
72 {
73 return this.unregisterServletDelegateMethodName;
74 }
75
76
77
78
79
80 public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName)
81 {
82 this.registerServletDelegateMethodName = registerServletDelegateMethodName;
83 }
84
85
86
87
88
89 public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName)
90 {
91 this.unregisterServletDelegateMethodName = unregisterServletDelegateMethodName;
92 }
93
94
95
96
97 public void setNestedConnector(NestedConnector nestedConnector)
98 {
99 this.nestedConnector = nestedConnector;
100 }
101
102
103
104 public NestedConnector getNestedConnector()
105 {
106 return this.nestedConnector;
107 }
108
109 @Override
110 public void lifeCycleStarted(LifeCycle event)
111 {
112 try
113 {
114 registerWithBridgeServlet();
115 }
116 catch (Exception e)
117 {
118 if (e instanceof RuntimeException)
119 {
120 throw (RuntimeException)e;
121 }
122 throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e);
123 }
124 }
125
126 @Override
127 public void lifeCycleStopping(LifeCycle event)
128 {
129 try
130 {
131 unregisterWithBridgeServlet();
132 }
133 catch (Exception e)
134 {
135 if (e instanceof RuntimeException)
136 {
137 throw (RuntimeException)e;
138 }
139 throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e);
140 }
141 }
142
143
144
145
146 protected void registerWithBridgeServlet() throws Exception
147 {
148 _servletDelegate = new NestedConnectorServletDelegate(getNestedConnector());
149 try
150 {
151 invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(),
152 new Class[] {HttpServlet.class}, _servletDelegate);
153 }
154 catch (Throwable t)
155 {
156 _servletDelegate.destroy();
157 _servletDelegate = null;
158 if (t instanceof Exception)
159 {
160 throw (Exception)t;
161 }
162 throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t);
163 }
164 }
165
166
167
168
169 protected void unregisterWithBridgeServlet() throws Exception
170 {
171 if (_servletDelegate != null)
172 {
173 try
174 {
175 invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(),
176 new Class[] {HttpServlet.class}, _servletDelegate);
177 }
178 catch (Throwable t)
179 {
180 if (t instanceof Exception)
181 {
182 throw (Exception)t;
183 }
184 throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t);
185 }
186 finally
187 {
188 _servletDelegate.destroy();
189 _servletDelegate = null;
190 }
191 }
192 }
193
194
195
196
197
198
199
200
201 private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object...args)
202 throws Exception
203 {
204 Method m = getMethod(clName, methName, argType);
205 m.invoke(null, args);
206 }
207
208
209
210
211
212
213
214
215 private static Method getMethod(String clName, String methName, Class... argType)
216 throws Exception
217 {
218 Class bridgeServletClass = FrameworkUtil.class.getClassLoader()
219 .loadClass(clName);
220 return getMethod(bridgeServletClass, methName, argType);
221 }
222 private static Method getMethod(Class cl, String methName, Class... argType)
223 throws Exception
224 {
225 Method meth = null;
226 try
227 {
228 meth = cl.getMethod(methName, argType);
229 return meth;
230 }
231 catch (Exception e)
232 {
233 for (Method m : cl.getMethods())
234 {
235 if (m.getName().equals(methName) && m.getParameterTypes().length == argType.length)
236 {
237 int i = 0;
238 for (Class p : m.getParameterTypes())
239 {
240 Class ap = argType[i];
241 if (p.getName().equals(ap.getName())
242 && !p.equals(ap))
243 {
244 throw new IllegalStateException("The method \"" + m.toGenericString() +
245 "\" was found. but the parameter class " + p.getName() + " is not the same " +
246 " inside OSGi classloader (" + ap.getClassLoader() + ") and inside the " +
247 cl.getName() + " classloader (" + p.getClassLoader() + ")." +
248 " Are the ExtensionBundles correctly defined?");
249
250 }
251 }
252 }
253 }
254 throw e;
255 }
256 }
257 }