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, plugin); 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 }