AndroidGDataClientpublic class AndroidGDataClient extends Object implements com.google.wireless.gdata.client.GDataClientImplementation of a GDataClient using GoogleHttpClient to make HTTP
requests. Always issues GETs and POSTs, using the X-HTTP-Method-Override
header when a PUT or DELETE is desired, to avoid issues with firewalls, etc.,
that do not allow methods other than GET or POST. |
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG | private static final boolean | LOCAL_LOGV | private static final String | X_HTTP_METHOD_OVERRIDE | private static final String | DEFAULT_USER_AGENT_APP_VERSION | private static final int | MAX_REDIRECTS | private final com.google.android.net.GoogleHttpClient | mHttpClient | private android.content.ContentResolver | mResolver |
Constructors Summary |
---|
public AndroidGDataClient(android.content.ContentResolver resolver)
mHttpClient = new GoogleHttpClient(resolver, DEFAULT_USER_AGENT_APP_VERSION,
true /* gzip capable */);
mHttpClient.enableCurlLogging(TAG, Log.VERBOSE);
mResolver = resolver;
| public AndroidGDataClient(android.content.Context context)Creates a new AndroidGDataClient.
this(context, DEFAULT_USER_AGENT_APP_VERSION);
| public AndroidGDataClient(android.content.Context context, String appAndVersion)Creates a new AndroidGDataClient.
mHttpClient = new GoogleHttpClient(context, appAndVersion,
true /* gzip capable */);
mHttpClient.enableCurlLogging(TAG, Log.VERBOSE);
mResolver = context.getContentResolver();
|
Methods Summary |
---|
public void | close()
mHttpClient.close();
| private java.io.InputStream | createAndExecuteMethod(com.google.android.gdata.client.AndroidGDataClient$HttpRequestCreator creator, java.lang.String uriString, java.lang.String authToken)
HttpResponse response = null;
int status = 500;
int redirectsLeft = MAX_REDIRECTS;
URI uri;
try {
uri = new URI(uriString);
} catch (URISyntaxException use) {
Log.w(TAG, "Unable to parse " + uriString + " as URI.", use);
throw new IOException("Unable to parse " + uriString + " as URI: "
+ use.getMessage());
}
// we follow redirects ourselves, since we want to follow redirects even on POSTs, which
// the HTTP library does not do. following redirects ourselves also allows us to log
// the redirects using our own logging.
while (redirectsLeft > 0) {
HttpUriRequest request = creator.createRequest(uri);
AndroidHttpClient.modifyRequestToAcceptGzipResponse(request);
// only add the auth token if not null (to allow for GData feeds that do not require
// authentication.)
if (!TextUtils.isEmpty(authToken)) {
request.addHeader("Authorization", "GoogleLogin auth=" + authToken);
}
if (LOCAL_LOGV) {
for (Header h : request.getAllHeaders()) {
Log.v(TAG, h.getName() + ": " + h.getValue());
}
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Executing " + request.getRequestLine().toString());
}
response = null;
try {
response = mHttpClient.execute(request);
} catch (IOException ioe) {
Log.w(TAG, "Unable to execute HTTP request." + ioe);
throw ioe;
}
StatusLine statusLine = response.getStatusLine();
if (statusLine == null) {
Log.w(TAG, "StatusLine is null.");
throw new NullPointerException("StatusLine is null -- should not happen.");
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, response.getStatusLine().toString());
for (Header h : response.getAllHeaders()) {
Log.d(TAG, h.getName() + ": " + h.getValue());
}
}
status = statusLine.getStatusCode();
HttpEntity entity = response.getEntity();
if ((status >= 200) && (status < 300) && entity != null) {
InputStream in = AndroidHttpClient.getUngzippedContent(entity);
if (Log.isLoggable(TAG, Log.DEBUG)) {
in = logInputStreamContents(in);
}
return in;
}
// TODO: handle 301, 307?
// TODO: let the http client handle the redirects, if we can be sure we'll never get a
// redirect on POST.
if (status == 302) {
// consume the content, so the connection can be closed.
entity.consumeContent();
Header location = response.getFirstHeader("Location");
if (location == null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Redirect requested but no Location "
+ "specified.");
}
break;
}
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Following redirect to " + location.getValue());
}
try {
uri = new URI(location.getValue());
} catch (URISyntaxException use) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Unable to parse " + location.getValue() + " as URI.", use);
throw new IOException("Unable to parse " + location.getValue()
+ " as URI.");
}
break;
}
--redirectsLeft;
} else {
break;
}
}
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Received " + status + " status code.");
}
String errorMessage = null;
HttpEntity entity = response.getEntity();
try {
if (response != null && entity != null) {
InputStream in = AndroidHttpClient.getUngzippedContent(entity);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
int bytesRead = -1;
while ((bytesRead = in.read(buf)) != -1) {
baos.write(buf, 0, bytesRead);
}
// TODO: use appropriate encoding, picked up from Content-Type.
errorMessage = new String(baos.toByteArray());
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, errorMessage);
}
}
} finally {
if (entity != null) {
entity.consumeContent();
}
}
String exceptionMessage = "Received " + status + " status code";
if (errorMessage != null) {
exceptionMessage += (": " + errorMessage);
}
throw new HttpException(exceptionMessage, status, null /* InputStream */);
| private org.apache.http.HttpEntity | createEntityForEntry(com.google.wireless.gdata.serializer.GDataSerializer entry, int format)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
entry.serialize(baos, format);
} catch (IOException ioe) {
Log.e(TAG, "Unable to serialize entry.", ioe);
throw ioe;
} catch (ParseException pe) {
Log.e(TAG, "Unable to serialize entry.", pe);
throw new IOException("Unable to serialize entry: " + pe.getMessage());
}
byte[] entryBytes = baos.toByteArray();
if (entryBytes != null && Log.isLoggable(TAG, Log.DEBUG)) {
try {
Log.d(TAG, "Serialized entry: " + new String(entryBytes, "UTF-8"));
} catch (UnsupportedEncodingException uee) {
// should not happen
throw new IllegalStateException("UTF-8 should be supported!",
uee);
}
}
AbstractHttpEntity entity = AndroidHttpClient.getCompressedEntity(entryBytes, mResolver);
entity.setContentType(entry.getContentType());
return entity;
| public java.io.InputStream | createEntry(java.lang.String feedUrl, java.lang.String authToken, com.google.wireless.gdata.serializer.GDataSerializer entry)
HttpEntity entity = createEntityForEntry(entry, GDataSerializer.FORMAT_CREATE);
InputStream in = createAndExecuteMethod(
new PostRequestCreator(null /* override */, entity),
feedUrl,
authToken);
if (in != null) {
return in;
}
throw new IOException("Unable to create entry.");
| public com.google.wireless.gdata.client.QueryParams | createQueryParams()
return new QueryParamsImpl();
| public void | deleteEntry(java.lang.String editUri, java.lang.String authToken)
if (StringUtils.isEmpty(editUri)) {
throw new IllegalArgumentException(
"you must specify an non-empty edit url");
}
InputStream in =
createAndExecuteMethod(
new PostRequestCreator("DELETE", null /* entity */),
editUri,
authToken);
if (in == null) {
throw new IOException("Unable to delete entry.");
}
try {
in.close();
} catch (IOException ioe) {
// ignore
}
| public java.lang.String | encodeUri(java.lang.String uri)
String encodedUri;
try {
encodedUri = URLEncoder.encode(uri, "UTF-8");
} catch (UnsupportedEncodingException uee) {
// should not happen.
Log.e("JakartaGDataClient",
"UTF-8 not supported -- should not happen. "
+ "Using default encoding.", uee);
encodedUri = URLEncoder.encode(uri);
}
return encodedUri;
| public java.io.InputStream | getFeedAsStream(java.lang.String feedUrl, java.lang.String authToken)
InputStream in = createAndExecuteMethod(new GetRequestCreator(), feedUrl, authToken);
if (in != null) {
return in;
}
throw new IOException("Unable to access feed.");
| public java.io.InputStream | getMediaEntryAsStream(java.lang.String mediaEntryUrl, java.lang.String authToken)
InputStream in = createAndExecuteMethod(new GetRequestCreator(), mediaEntryUrl, authToken);
if (in != null) {
return in;
}
throw new IOException("Unable to access media entry.");
| private java.io.InputStream | logInputStreamContents(java.io.InputStream in)Log the contents of the input stream.
The original input stream is consumed, so the caller must use the
BufferedInputStream that is returned.
if (in == null) {
return in;
}
// bufferSize is the (arbitrary) maximum amount to log.
// The original InputStream is wrapped in a
// BufferedInputStream with a 16K buffer. This lets
// us read up to 16K, write it to the log, and then
// reset the stream so the the original client can
// then read the data. The BufferedInputStream
// provides the mark and reset support, even when
// the original InputStream does not.
final int bufferSize = 16384;
BufferedInputStream bin = new BufferedInputStream(in, bufferSize);
bin.mark(bufferSize);
int wanted = bufferSize;
int totalReceived = 0;
byte buf[] = new byte[wanted];
while (wanted > 0) {
int got = bin.read(buf, totalReceived, wanted);
if (got <= 0) break; // EOF
wanted -= got;
totalReceived += got;
}
Log.d(TAG, new String(buf, 0, totalReceived, "UTF-8"));
bin.reset();
return bin;
| public java.io.InputStream | updateEntry(java.lang.String editUri, java.lang.String authToken, com.google.wireless.gdata.serializer.GDataSerializer entry)
HttpEntity entity = createEntityForEntry(entry, GDataSerializer.FORMAT_UPDATE);
InputStream in = createAndExecuteMethod(
new PostRequestCreator("PUT", entity),
editUri,
authToken);
if (in != null) {
return in;
}
throw new IOException("Unable to update entry.");
| public java.io.InputStream | updateMediaEntry(java.lang.String editUri, java.lang.String authToken, java.io.InputStream mediaEntryInputStream, java.lang.String contentType)
InputStream in = createAndExecuteMethod(
new MediaPutRequestCreator(mediaEntryInputStream, contentType),
editUri,
authToken);
if (in != null) {
return in;
}
throw new IOException("Unable to write media entry.");
|
|