1 package com.atlassian.plugins.rest.module.jersey;
2
3 import com.atlassian.plugin.AutowireCapablePlugin;
4 import com.atlassian.plugin.Plugin;
5 import com.atlassian.plugins.rest.module.ChainingClassLoader;
6 import com.atlassian.plugins.rest.module.ContextClassLoaderSwitchingProxy;
7 import com.atlassian.sal.api.net.NonMarshallingRequestFactory;
8 import com.atlassian.sal.api.net.Request;
9 import com.atlassian.sal.api.net.RequestFactory;
10 import org.osgi.framework.Bundle;
11
12 import java.lang.reflect.Proxy;
13
14 public class JerseyRequestFactory implements RequestFactory
15 {
16 private final RequestFactory<? extends Request> delegateRequestFactory;
17 private final Plugin plugin;
18 private final Bundle bundle;
19
20 private volatile JerseyEntityHandler jerseyEntityHandler;
21
22 public JerseyRequestFactory(final NonMarshallingRequestFactory<? extends Request> delegateRequestFactory,
23 final Plugin plugin,
24 final Bundle bundle)
25 {
26 this.plugin = plugin;
27 this.delegateRequestFactory = delegateRequestFactory;
28 this.bundle = bundle;
29 }
30
31 public Request createRequest(final Request.MethodType methodType, final String s)
32 {
33 ensureInitalised();
34 final Request delegateRequest = delegateRequestFactory.createRequest(methodType, s);
35 final JerseyRequest request = new JerseyRequest(delegateRequest, jerseyEntityHandler);
36 return (Request) Proxy.newProxyInstance(
37 getClass().getClassLoader(),
38 new Class[]{Request.class},
39 new ContextClassLoaderSwitchingProxy(request, getChainingClassLoader(plugin))
40 );
41 }
42
43 public boolean supportsHeader()
44 {
45 ensureInitalised();
46 return delegateRequestFactory.supportsHeader();
47 }
48
49 private void ensureInitalised()
50 {
51 if (jerseyEntityHandler == null)
52 {
53 jerseyEntityHandler = createHandler();
54 }
55 }
56
57 private JerseyEntityHandler createHandler()
58 {
59 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
60 ChainingClassLoader chainingClassLoader = getChainingClassLoader(plugin);
61 try
62 {
63 Thread.currentThread().setContextClassLoader(chainingClassLoader);
64 return new JerseyEntityHandler((AutowireCapablePlugin) plugin, bundle);
65 }
66 finally
67 {
68 Thread.currentThread().setContextClassLoader(oldClassLoader);
69 }
70 }
71
72 void destroy()
73 {
74 if (jerseyEntityHandler != null) {
75 jerseyEntityHandler.destroy();
76 }
77 }
78
79 private ChainingClassLoader getChainingClassLoader(final Plugin plugin)
80 {
81 return new ChainingClassLoader(getClass().getClassLoader(), plugin.getClassLoader());
82 }
83 }