1   package com.atlassian.plugins.rest.module.jersey;
2   
3   import com.atlassian.sal.api.net.Request;
4   import com.atlassian.sal.api.net.Response;
5   import com.atlassian.sal.api.net.ResponseException;
6   import com.atlassian.sal.api.net.ResponseHandler;
7   import com.atlassian.sal.api.net.auth.Authenticator;
8   
9   import javax.ws.rs.core.HttpHeaders;
10  import javax.ws.rs.core.MediaType;
11  import java.io.IOException;
12  import java.nio.charset.Charset;
13  import java.util.List;
14  import java.util.Map;
15  
16  import static org.apache.commons.lang.Validate.notNull;
17  
18  public class JerseyRequest implements Request<JerseyRequest, JerseyResponse>
19  {
20      private final Request delegateRequest;
21      private final JerseyEntityHandler jerseyEntityHandler;
22  
23      private Object entity;
24  
25      public JerseyRequest(final Request delegateRequest, final JerseyEntityHandler jerseyEntityHandler)
26      {
27          this.delegateRequest = delegateRequest;
28          this.jerseyEntityHandler = jerseyEntityHandler;
29      }
30  
31      public JerseyRequest setEntity(final Object entity)
32      {
33          notNull(entity);
34          this.entity = entity;
35          return this;
36      }
37  
38      public JerseyRequest setConnectionTimeout(final int i)
39      {
40          delegateRequest.setConnectionTimeout(i);
41          return this;
42      }
43  
44      public JerseyRequest setSoTimeout(final int i)
45      {
46          delegateRequest.setSoTimeout(i);
47          return this;
48      }
49  
50      public JerseyRequest setUrl(final String s)
51      {
52          delegateRequest.setUrl(s);
53          return this;
54      }
55  
56      public JerseyRequest setRequestBody(final String s)
57      {
58          delegateRequest.setRequestBody(s);
59          return this;
60      }
61  
62      public JerseyRequest setRequestContentType(final String s)
63      {
64          delegateRequest.setRequestContentType(s);
65          return this;
66      }
67  
68      public JerseyRequest addRequestParameters(final String... strings)
69      {
70          delegateRequest.addRequestParameters(strings);
71          return this;
72      }
73  
74      public JerseyRequest addAuthentication(final Authenticator authenticator)
75      {
76          delegateRequest.addAuthentication(authenticator);
77          return this;
78      }
79  
80      public JerseyRequest addTrustedTokenAuthentication()
81      {
82          delegateRequest.addTrustedTokenAuthentication();
83          return this;
84      }
85  
86      public JerseyRequest addTrustedTokenAuthentication(final String s)
87      {
88          delegateRequest.addTrustedTokenAuthentication(s);
89          return this;
90      }
91  
92      public JerseyRequest addBasicAuthentication(final String s, final String s1)
93      {
94          delegateRequest.addBasicAuthentication(s, s1);
95          return this;
96      }
97  
98      public JerseyRequest addSeraphAuthentication(final String s, final String s1)
99      {
100         delegateRequest.addSeraphAuthentication(s, s1);
101         return this;
102     }
103 
104     public JerseyRequest addHeader(final String s, final String s1)
105     {
106         delegateRequest.addHeader(s, s1);
107         return this;
108     }
109 
110     public JerseyRequest setHeader(final String s, final String s1)
111     {
112         delegateRequest.setHeader(s, s1);
113         return this;
114     }
115 
116     public Map<String, List<String>> getHeaders()
117     {
118         return delegateRequest.getHeaders();
119     }
120 
121     public void execute(final ResponseHandler<JerseyResponse> responseHandler)
122             throws ResponseException
123     {
124         marshallEntity();
125         delegateRequest.execute(new ResponseHandler<Response>()
126         {
127             public void handle(final Response response) throws ResponseException
128             {
129                 JerseyResponse res = new JerseyResponse(response, jerseyEntityHandler);
130                 responseHandler.handle(res);
131             }
132         });
133     }
134 
135     public String execute()
136             throws ResponseException
137     {
138         marshallEntity();
139         return delegateRequest.execute();
140     }
141 
142     private void marshallEntity() throws EntityConversionException
143     {
144         if (entity != null)
145         {
146             String contentType = getOrSetSingleHeaderValue(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML);
147             String encoding = getOrSetSingleHeaderValue(HttpHeaders.CONTENT_ENCODING, "UTF-8");
148             getOrSetSingleHeaderValue(HttpHeaders.ACCEPT, contentType);
149             Charset charset = Charset.forName(encoding);
150             MediaType type;
151             try
152             {
153                 type = MediaType.valueOf(contentType);
154             }
155             catch (IllegalArgumentException e)
156             {
157                 throw new UnsupportedContentTypeException(e.getMessage(), e);
158             }
159 
160             try
161             {
162                 String body = jerseyEntityHandler.marshall(entity, type, charset);
163                 setRequestBody(body);
164                 setRequestContentType(contentType);
165             }
166             catch (IOException e)
167             {
168                 throw new EntityConversionException(e);
169             }
170         }
171     }
172 
173     /**
174      * Retrieve the specified header value, or set it to the supplied defaultValue if the header is currently unset.
175      */
176     private String getOrSetSingleHeaderValue(final String headerName, final String defaultValue)
177     {
178         String value = defaultValue;
179         List<String> headers = getHeaders().get(headerName);
180         if (headers != null && !headers.isEmpty())
181         {
182             if (headers.size() == 1)
183             {
184                 value = headers.get(0);
185             }
186         }
187         else
188         {
189             setHeader(headerName, defaultValue);
190         }
191         return value;
192     }
193 
194 }