OSDN Git Service

android-2.1_r1 snapshot
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / picasa / GDataClient.java
1 package com.cooliris.picasa;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.zip.GZIPInputStream;
7 import java.util.zip.GZIPOutputStream;
8
9 import org.apache.http.Header;
10 import org.apache.http.HttpEntity;
11 import org.apache.http.HttpResponse;
12 import org.apache.http.client.methods.HttpGet;
13 import org.apache.http.client.methods.HttpPost;
14 import org.apache.http.client.methods.HttpUriRequest;
15 import org.apache.http.client.params.HttpClientParams;
16 import org.apache.http.conn.scheme.PlainSocketFactory;
17 import org.apache.http.conn.scheme.Scheme;
18 import org.apache.http.conn.scheme.SchemeRegistry;
19 import org.apache.http.entity.ByteArrayEntity;
20 import org.apache.http.entity.InputStreamEntity;
21 import org.apache.http.impl.client.DefaultHttpClient;
22 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
23 import org.apache.http.params.BasicHttpParams;
24 import org.apache.http.params.HttpConnectionParams;
25 import org.apache.http.params.HttpParams;
26 import org.apache.http.params.HttpProtocolParams;
27
28 import android.text.TextUtils;
29 import android.util.Log;
30
31 public final class GDataClient {
32     private static final String TAG = "GDataClient";
33     private static final String USER_AGENT = "Cooliris-GData/1.0; gzip";
34     private static final String X_HTTP_METHOD_OVERRIDE = "X-HTTP-Method-Override";
35     private static final String IF_MATCH = "If-Match";
36     private static final int CONNECTION_TIMEOUT = 20000; // ms.
37     private static final int MIN_GZIP_SIZE = 512;
38     public static final HttpParams HTTP_PARAMS;
39     public static final ThreadSafeClientConnManager HTTP_CONNECTION_MANAGER;
40
41     private final DefaultHttpClient mHttpClient = new DefaultHttpClient(HTTP_CONNECTION_MANAGER, HTTP_PARAMS);
42     private String mAuthToken;
43
44     static {
45         // Prepare HTTP parameters.
46         HttpParams params = new BasicHttpParams();
47         HttpConnectionParams.setStaleCheckingEnabled(params, false);
48         HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
49         HttpConnectionParams.setSoTimeout(params, CONNECTION_TIMEOUT);
50         HttpClientParams.setRedirecting(params, true);
51         HttpProtocolParams.setUserAgent(params, USER_AGENT);
52         HTTP_PARAMS = params;
53
54         // Register HTTP protocol.
55         SchemeRegistry schemeRegistry = new SchemeRegistry();
56         schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
57
58         // Create the connection manager.
59         HTTP_CONNECTION_MANAGER = new ThreadSafeClientConnManager(params, schemeRegistry);
60     }
61
62     public static final class Operation {
63         public String inOutEtag;
64         public int outStatus;
65         public InputStream outBody;
66     }
67
68     public void setAuthToken(String authToken) {
69         mAuthToken = authToken;
70     }
71
72     public void get(String feedUrl, Operation operation) throws IOException {
73         callMethod(new HttpGet(feedUrl), operation);
74     }
75
76     public void post(String feedUrl, byte[] data, String contentType, Operation operation) throws IOException {
77         ByteArrayEntity entity = getCompressedEntity(data);
78         entity.setContentType(contentType);
79         HttpPost post = new HttpPost(feedUrl);
80         post.setEntity(entity);
81         callMethod(post, operation);
82     }
83
84     public void put(String feedUrl, byte[] data, String contentType, Operation operation) throws IOException {
85         ByteArrayEntity entity = getCompressedEntity(data);
86         entity.setContentType(contentType);
87         HttpPost post = new HttpPost(feedUrl);
88         post.setHeader(X_HTTP_METHOD_OVERRIDE, "PUT");
89         post.setEntity(entity);
90         callMethod(post, operation);
91     }
92
93     public void putStream(String feedUrl, InputStream stream, String contentType, Operation operation) throws IOException {
94         InputStreamEntity entity = new InputStreamEntity(stream, -1);
95         entity.setContentType(contentType);
96         HttpPost post = new HttpPost(feedUrl);
97         post.setHeader(X_HTTP_METHOD_OVERRIDE, "PUT");
98         post.setEntity(entity);
99         callMethod(post, operation);
100     }
101
102     public void delete(String feedUrl, Operation operation) throws IOException {
103         HttpPost post = new HttpPost(feedUrl);
104         String etag = operation.inOutEtag;
105         post.setHeader(X_HTTP_METHOD_OVERRIDE, "DELETE");
106         post.setHeader(IF_MATCH, etag != null ? etag : "*");
107         callMethod(post, operation);
108     }
109
110     private void callMethod(HttpUriRequest request, Operation operation) throws IOException {
111         // Specify GData protocol version 2.0.
112         request.addHeader("GData-Version", "2");
113
114         // Indicate support for gzip-compressed responses.
115         request.addHeader("Accept-Encoding", "gzip");
116
117         // Specify authorization token if provided.
118         String authToken = mAuthToken;
119         if (!TextUtils.isEmpty(authToken)) {
120             request.addHeader("Authorization", "GoogleLogin auth=" + authToken);
121         }
122
123         // Specify the ETag of a prior response, if available.
124         String etag = operation.inOutEtag;
125         if (etag != null) {
126             request.addHeader("If-None-Match", etag);
127         }
128
129         // Execute the HTTP request.
130         HttpResponse httpResponse = null;
131         try {
132             httpResponse = mHttpClient.execute(request);
133         } catch (IOException e) {
134             Log.w(TAG, "Request failed: " + request.getURI());
135             throw e;
136         }
137
138         // Get the status code and response body.
139         int status = httpResponse.getStatusLine().getStatusCode();
140         InputStream stream = null;
141         HttpEntity entity = httpResponse.getEntity();
142         if (entity != null) {
143             // Wrap the entity input stream in a GZIP decoder if necessary.
144             stream = entity.getContent();
145             if (stream != null) {
146                 Header header = entity.getContentEncoding();
147                 if (header != null) {
148                     if (header.getValue().contains("gzip")) {
149                         stream = new GZIPInputStream(stream);
150                     }
151                 }
152             }
153         }
154
155         // Return the stream if successful.
156         Header etagHeader = httpResponse.getFirstHeader("ETag");
157         operation.outStatus = status;
158         operation.inOutEtag = etagHeader != null ? etagHeader.getValue() : null;
159         operation.outBody = stream;
160     }
161
162     private ByteArrayEntity getCompressedEntity(byte[] data) throws IOException {
163         ByteArrayEntity entity;
164         if (data.length >= MIN_GZIP_SIZE) {
165             ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(data.length / 2);
166             GZIPOutputStream gzipOutput = new GZIPOutputStream(byteOutput);
167             gzipOutput.write(data);
168             gzipOutput.close();
169             entity = new ByteArrayEntity(byteOutput.toByteArray());
170         } else {
171             entity = new ByteArrayEntity(data);
172         }
173         return entity;
174     }
175
176     public static String inputStreamToString(InputStream stream) {
177         if (stream != null) {
178             try {
179                 ByteArrayOutputStream bytes = new ByteArrayOutputStream();
180                 byte[] buffer = new byte[4096];
181                 int bytesRead;
182                 while ((bytesRead = stream.read(buffer)) != -1) {
183                     bytes.write(buffer, 0, bytesRead);
184                 }
185                 return new String(bytes.toString());
186             } catch (IOException e) {
187                 // Fall through and return null.
188             }
189         }
190         return null;
191     }
192 }