Saturday, September 10, 2011

This is a test post to see how it'll look

Google's Data API (gdata) makes accessing their suite of tools and sites a lot easier than making direct HTTP calls to the Web-based service interfaces. But there don't seem to be too many code snippets out there--or at least not enough that do what I want to do. I have a document that was uploaded through a Servlet and is now sitting in a byte[] array. Now I want to upload that file to my app's Google Docs account. Here's what Google's documentation offers:
DocumentListEntry uploadedEntry = uploadFile("/path/to/your/file.doc", "TitleToUse");
System.out.println("Document now online @ :" + uploadedEntry.getHtmlLink().getHref());
public DocumentListEntry uploadFile(String filepath, String title)
throws IOException, ServiceException {
File file = new File(filepath);
DocumentListEntry newDocument = new DocumentListEntry();
String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
newDocument.setFile(new File(filepath), mimeType);
newDocument.setTitle(new PlainTextConstruct(title));
return client.insert(new URL("https://docs.google.com/feeds/documents/private/full/"), newDocument);
}
view raw gistfile1.java hosted with ❤ by GitHub
Fairly straightforward, but there's one catch: The setFile() method is expecting a java.io.File. Normally that isn't a problem, but if you're developing in Google App Engine (GAE), then you know that you can't create filesystem files. Digging through the DocumentListEntry code (thank you, Google, for making gdata open source!!) I was able to figure out how to avoid this File creation entirely:
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.data.MediaContent;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListEntry.MediaType;
import com.google.gdata.data.media.MediaByteArraySource;
import com.google.gdata.data.media.MediaSource;
import com.google.gdata.util.ContentType;
// ...skipping to the good part...
DocsService docsService = new DocsService("myname-webapp-1.0");
// Authenticate our direct user access (using direct login credentials)
docsService.setUserCredentials(MY_USER_NAME, MY_PASSWORD);
DocumentListEntry newDocument = new DocumentListEntry();
// Load the byte array into a MediaSource
MediaByteArraySource mediaSource = new MediaByteArraySource(byteData, MediaType.fromFileName(myFileName).getMimeType());
MediaContent content = new MediaContent();
content.setMediaSource(mediaSource);
content.setMimeType(new ContentType(mediaSource.getContentType()));
newDocument.setContent(content);
String gdocsFilename = new String("My Filename");
newDocument.setTitle(new PlainTextConstruct(gdocsFilename));
// Push it into Google Docs!!
DocumentListEntry uploadedRef = docsService.insert(new URL("https://docs.google.com/feeds/default/private/full/"), newDocument);
Voila! MediaByteArraySource allows us to read from the byte[] array directly without first creating a java.io.File. And then, after jumping through a few hoops, we're able to setContent() to attach it to the new DocumentListEntry that will be pushed into Google Docs. Oh, and I'm using direct username/password access because this is my app talking to the app's own Google Docs account. I'm sure it would be a better idea to use an authenticated token, but that just seemed like way too much work for one part of my app to talk to another part of itself.

No comments:

Post a Comment