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
21
22
23 private volatile JerseyEntityHandler jerseyEntityHandler;
24
25 public JerseyRequestFactory(NonMarshallingRequestFactory<? extends Request> delegateRequestFactory, Plugin plugin, Bundle bundle)
26 {
27 this.plugin = plugin;
28 this.delegateRequestFactory = delegateRequestFactory;
29 this.bundle = bundle;
30 }
31
32 public Request createRequest(final Request.MethodType methodType, final String s)
33 {
34 ensureInitalised();
35 ChainingClassLoader chainingClassLoader = getChainingClassLoader(plugin);
36 Request delegateRequest = delegateRequestFactory.createRequest(methodType, s);
37 JerseyRequest request = new JerseyRequest(delegateRequest, jerseyEntityHandler);
38 return (Request) Proxy.newProxyInstance(
39 getClass().getClassLoader(),
40 new Class[]{Request.class},
41 new ContextClassLoaderSwitchingProxy(request, chainingClassLoader)
42 );
43 }
44
45 public boolean supportsHeader()
46 {
47 ensureInitalised();
48 return delegateRequestFactory.supportsHeader();
49 }
50
51 private void ensureInitalised()
52 {
53 if (jerseyEntityHandler == null)
54 {
55 throw new IllegalStateException("Must call init() before use");
56 }
57 }
58
59 void destroy()
60 {
61 jerseyEntityHandler.destroy();
62 }
63
64 void init()
65 {
66 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
67 ChainingClassLoader chainingClassLoader = getChainingClassLoader(plugin);
68 try
69 {
70 Thread.currentThread().setContextClassLoader(chainingClassLoader);
71 jerseyEntityHandler = new JerseyEntityHandler((AutowireCapablePlugin) plugin, bundle);
72 }
73 finally
74 {
75 Thread.currentThread().setContextClassLoader(oldClassLoader);
76 }
77 }
78
79 private ChainingClassLoader getChainingClassLoader(final Plugin plugin)
80 {
81 return new ChainingClassLoader(getClass().getClassLoader(), plugin.getClassLoader());
82 }
83 }