1   package com.atlassian.plugins.rest.module.jersey;
2   
3   import com.atlassian.plugin.Plugin;
4   import com.atlassian.plugins.rest.module.ChainingClassLoader;
5   import com.atlassian.sal.api.net.Response;
6   import com.atlassian.sal.api.net.ResponseException;
7   
8   import java.io.IOException;
9   import java.io.InputStream;
10  import java.util.Collections;
11  import java.util.HashMap;
12  import java.util.List;
13  import java.util.Map;
14  import javax.ws.rs.core.HttpHeaders;
15  import javax.ws.rs.core.MediaType;
16  
17  public class JerseyResponse implements Response
18  {
19      private final Response delegateResponse;
20      private final JerseyEntityHandler jerseyEntityHandler;
21      private final Plugin plugin;
22  
23      public JerseyResponse(Response delegateResponse, JerseyEntityHandler jerseyEntityHandler, Plugin plugin)
24      {
25          this.delegateResponse = delegateResponse;
26          this.jerseyEntityHandler = jerseyEntityHandler;
27          this.plugin = plugin;
28      }
29  
30      public <T> T getEntity(final Class<T> entityClass) throws ResponseException
31      {
32          Map<String, String> headers = getHeaders();
33          Map<String, List<String>> headerListMap = new HashMap<String, List<String>>();
34          for (final Map.Entry<String, String> entry : headers.entrySet())
35          {
36              headerListMap.put(entry.getKey(), Collections.singletonList(entry.getValue()));
37          }
38          String contentType = HeaderHelper.getSingleHeaderValue(headerListMap, HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML);
39          InputStream entityStream = getResponseBodyAsStream();
40  
41          ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
42          ChainingClassLoader chainingClassLoader = getChainingClassLoader(plugin);
43          try
44          {
45              Thread.currentThread().setContextClassLoader(chainingClassLoader);
46              return jerseyEntityHandler.unmarshall(entityClass, MediaType.valueOf(contentType), entityStream, headerListMap);
47          }
48          catch (IOException e)
49          {
50              throw new EntityConversionException(e);
51          }
52          finally
53          {
54              Thread.currentThread().setContextClassLoader(oldClassLoader);
55          }
56      }
57  
58      public int getStatusCode()
59      {
60          return delegateResponse.getStatusCode();
61      }
62  
63      public String getResponseBodyAsString()
64              throws ResponseException
65      {
66          return delegateResponse.getResponseBodyAsString();
67      }
68  
69      public InputStream getResponseBodyAsStream()
70              throws ResponseException
71      {
72          return delegateResponse.getResponseBodyAsStream();
73      }
74  
75      public String getStatusText()
76      {
77          return delegateResponse.getStatusText();
78      }
79  
80      public boolean isSuccessful()
81      {
82          return delegateResponse.isSuccessful();
83      }
84  
85      public String getHeader(final String s)
86      {
87          return delegateResponse.getHeader(s);
88      }
89  
90      public Map<String, String> getHeaders()
91      {
92          return delegateResponse.getHeaders();
93      }
94  
95      private ChainingClassLoader getChainingClassLoader(final Plugin plugin)
96      {
97          return new ChainingClassLoader(getClass().getClassLoader(), plugin.getClassLoader());
98      }
99  }