1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package groovyx.net.http;
23
24 import groovy.lang.Closure;
25 import groovy.lang.Writable;
26 import groovy.xml.StreamingMarkupBuilder;
27 import groovyx.net.http.HTTPBuilder.SendDelegate;
28
29 import java.io.BufferedReader;
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.PrintWriter;
35 import java.io.Reader;
36 import java.io.StringWriter;
37 import java.io.UnsupportedEncodingException;
38 import java.nio.charset.Charset;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43
44 import net.sf.json.JSON;
45 import net.sf.json.JSONObject;
46 import net.sf.json.groovy.JsonGroovyBuilder;
47
48 import org.apache.http.HttpEntity;
49 import org.apache.http.HttpEntityEnclosingRequest;
50 import org.apache.http.NameValuePair;
51 import org.apache.http.client.entity.UrlEncodedFormEntity;
52 import org.apache.http.entity.InputStreamEntity;
53 import org.apache.http.entity.StringEntity;
54 import org.apache.http.message.BasicNameValuePair;
55 import org.codehaus.groovy.runtime.MethodClosure;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public class EncoderRegistry {
74
75 Charset charset = Charset.defaultCharset();
76
77
78
79
80
81
82
83 public void setCharset( String charset ) {
84 this.charset = Charset.forName(charset);
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public InputStreamEntity encodeStream( Object data ) throws UnsupportedEncodingException {
103 if ( data instanceof InputStream ) {
104 return new InputStreamEntity( (InputStream)data, -1 );
105 }
106 else if ( data instanceof ByteArrayInputStream ) {
107 ByteArrayInputStream in = ((ByteArrayInputStream)data);
108 return new InputStreamEntity( in, in.available() );
109 }
110 else if ( data instanceof ByteArrayOutputStream ) {
111 ByteArrayOutputStream out = ((ByteArrayOutputStream)data);
112 return new InputStreamEntity( new ByteArrayInputStream(
113 out.toByteArray()), out.size() );
114 }
115 else if ( data instanceof Closure ) {
116 ByteArrayOutputStream out = new ByteArrayOutputStream();
117 ((Closure)data).call( out );
118 return new InputStreamEntity( new ByteArrayInputStream(out.toByteArray()), out.size() );
119 }
120 throw new IllegalArgumentException( "Don't know how to encode " + data + " as a byte stream" );
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public HttpEntity encodeText( Object data ) throws IOException {
139 if ( data instanceof Closure ) {
140 StringWriter out = new StringWriter();
141 PrintWriter writer = new PrintWriter( out );
142 ((Closure)data).call( writer );
143 writer.close();
144 out.flush();
145 data = out;
146 }
147 else if ( data instanceof Writable ) {
148 StringWriter out = new StringWriter();
149 ((Writable)data).writeTo(out);
150 out.flush();
151 data = out;
152 }
153 else if ( data instanceof Reader && ! (data instanceof BufferedReader) )
154 data = new BufferedReader( (Reader)data );
155 if ( data instanceof BufferedReader ) {
156 StringBuilder sb = new StringBuilder();
157 BufferedReader reader = (BufferedReader)data;
158 String line = null;
159 while( (line = reader.readLine()) != null )
160 sb.append( line );
161
162 data = sb;
163 }
164
165 return createEntity( ContentType.TEXT, data.toString() );
166 }
167
168
169
170
171
172
173
174
175 public UrlEncodedFormEntity encodeForm( Map<String,Object> params )
176 throws UnsupportedEncodingException {
177 List<NameValuePair> paramList = new ArrayList<NameValuePair>();
178
179 for ( Map.Entry<String, Object> entry : params.entrySet() )
180 paramList.add( new BasicNameValuePair(entry.getKey(),
181 entry.getValue().toString()) );
182
183 return new UrlEncodedFormEntity( paramList, charset.name() );
184 }
185
186
187
188
189
190
191
192 public HttpEntity encodeXML( Closure xmlBuilder ) throws UnsupportedEncodingException {
193 StreamingMarkupBuilder smb = new StreamingMarkupBuilder();
194 String markup = smb.bind( xmlBuilder ).toString();
195 return createEntity( ContentType.XML, markup);
196 }
197
198
199
200
201
202
203
204
205
206
207 @SuppressWarnings("unchecked")
208 public HttpEntity encodeJSON( Object model ) throws UnsupportedEncodingException {
209 JSON json;
210
211 if ( model instanceof Map ) {
212 json = new JSONObject();
213 ((JSONObject)json).putAll( (Map)model );
214 }
215 else if ( model instanceof Closure ) {
216 Closure closure = (Closure)model;
217 closure.setDelegate( new JsonGroovyBuilder() );
218 json = (JSONObject)closure.call();
219 }
220 else json = JSONObject.fromObject( model );
221
222 return this.createEntity( ContentType.JSON, json.toString() );
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237 protected StringEntity createEntity( ContentType ct, String data )
238 throws UnsupportedEncodingException {
239 StringEntity entity = new StringEntity( data, charset.toString() );
240 entity.setContentType( ct.toString() );
241 return entity;
242 }
243
244 protected Map<String,Closure> registeredEncoders = buildDefaultEncoderMap();
245
246
247
248
249
250
251
252
253
254 public void register( String contentType, Closure closure ) {
255 registeredEncoders.put( contentType, closure );
256 }
257
258
259
260
261
262
263
264
265 Closure get( String contentType ) { return registeredEncoders.get(contentType); }
266
267
268
269
270
271
272
273 protected Map<String,Closure> buildDefaultEncoderMap() {
274 Map<String,Closure> encoders = new HashMap<String,Closure>();
275
276 encoders.put( ContentType.BINARY.toString(), new MethodClosure(this,"encodeStream") );
277 encoders.put( ContentType.TEXT.toString(), new MethodClosure( this, "encodeText" ) );
278 encoders.put( ContentType.URLENC.toString(), new MethodClosure( this, "encodeForm" ) );
279
280 Closure encClosure = new MethodClosure(this,"encodeXML");
281 for ( String ct : ContentType.XML.getContentTypeStrings() )
282 encoders.put( ct, encClosure );
283 encoders.put( ContentType.HTML.toString(), encClosure );
284
285 encClosure = new MethodClosure(this,"encodeJSON");
286 for ( String ct : ContentType.JSON.getContentTypeStrings() )
287 encoders.put( ct, encClosure );
288
289 return encoders;
290 }
291 }