/* Copyright (c) 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package sample.blogger; import com.google.gdata.client.Query; import com.google.gdata.client.blogger.BloggerService; import sample.util.SimpleCommandLineParser; import com.google.gdata.data.DateTime; import com.google.gdata.data.Entry; import com.google.gdata.data.Feed; import com.google.gdata.data.Person; import com.google.gdata.data.PlainTextConstruct; import com.google.gdata.data.TextContent; import com.google.gdata.util.ServiceException; import java.io.IOException; import java.net.URL; /** * Demonstrates how to use the Google Data API's Java client library to * interface with the Blogger service. There are examples for the following * operations: * * <ol> * <li>Retrieving the list of all the user's blogs</li> * <li>Retrieving all posts on a single blog</li> * <li>Performing a date-range query for posts on a blog</li> * <li>Creating draft posts and publishing posts</li> * <li>Updating posts</li> * <li>Retrieving comments</li> * <li>Deleting posts</li> * </ol> * * */ public class BloggerClient { private static final String METAFEED_URL = "http://www.blogger.com/feeds/default/blogs"; private static final String FEED_URI_BASE = "http://www.blogger.com/feeds"; private static final String POSTS_FEED_URI_SUFFIX = "/posts/default"; private static final String COMMENTS_FEED_URI_SUFFIX = "/comments/default"; private static String feedUri; /** * Utility classes should not have a public or default constructor. */ private BloggerClient() { // do nothing } /** * Parses the metafeed to get the blog ID for the authenticated user's default * blog. * * @param myService An authenticated GoogleService object. * @return A String representation of the blog's ID. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ private static String getBlogId(BloggerService myService) throws ServiceException, IOException { // Get the metafeed final URL feedUrl = new URL(METAFEED_URL); Feed resultFeed = myService.getFeed(feedUrl, Feed.class); // If the user has a blog then return the id (which comes after 'blog-') if (resultFeed.getEntries().size() > 0) { Entry entry = resultFeed.getEntries().get(0); return entry.getId().split("blog-")[1]; } throw new IOException("User has no blogs!"); } /** * Prints a list of all the user's blogs. * * @param myService An authenticated GoogleService object. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static void printUserBlogs(BloggerService myService) throws ServiceException, IOException { // Request the feed final URL feedUrl = new URL(METAFEED_URL); Feed resultFeed = myService.getFeed(feedUrl, Feed.class); // Print the results System.out.println(resultFeed.getTitle().getPlainText()); for (int i = 0; i < resultFeed.getEntries().size(); i++) { Entry entry = resultFeed.getEntries().get(i); System.out.println("\t" + entry.getTitle().getPlainText()); } System.out.println(); } /** * Creates a new post on a blog. The new post can be stored as a draft or * published based on the value of the isDraft paramter. The method creates an * Entry for the new post using the title, content, authorName and isDraft * parameters. Then it uses the given GoogleService to insert the new post. If * the insertion is successful, the added post will be returned. * * @param myService An authenticated GoogleService object. * @param title Text for the title of the post to create. * @param content Text for the content of the post to create. * @param authorName Display name of the author of the post. * @param userName username of the author of the post. * @param isDraft True to save the post as a draft, False to publish the post. * @return An Entry containing the newly-created post. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static Entry createPost(BloggerService myService, String title, String content, String authorName, String userName, Boolean isDraft) throws ServiceException, IOException { // Create the entry to insert Entry myEntry = new Entry(); myEntry.setTitle(new PlainTextConstruct(title)); myEntry.setContent(new PlainTextConstruct(content)); Person author = new Person(authorName, null, userName); myEntry.getAuthors().add(author); myEntry.setDraft(isDraft); // Ask the service to insert the new entry URL postUrl = new URL(feedUri + POSTS_FEED_URI_SUFFIX); return myService.insert(postUrl, myEntry); } /** * Displays the titles of all the posts in a blog. First it requests the posts * feed for the blogs and then is prints the results. * * @param myService An authenticated GoogleService object. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static void printAllPosts(BloggerService myService) throws ServiceException, IOException { // Request the feed URL feedUrl = new URL(feedUri + POSTS_FEED_URI_SUFFIX); Feed resultFeed = myService.getFeed(feedUrl, Feed.class); // Print the results System.out.println(resultFeed.getTitle().getPlainText()); for (int i = 0; i < resultFeed.getEntries().size(); i++) { Entry entry = resultFeed.getEntries().get(i); System.out.println("\t" + entry.getTitle().getPlainText()); } System.out.println(); } /** * Displays the title and modification time for any posts that have been * created or updated in the period between the startTime and endTime * parameters. The method creates the query, submits it to the GoogleService, * then displays the results. * * Note that while the startTime is inclusive, the endTime is exclusive, so * specifying an endTime of '2007-7-1' will include those posts up until * 2007-6-30 11:59:59PM. * * @param myService An authenticated GoogleService object. * @param startTime DateTime object specifying the beginning of the search * period (inclusive). * @param endTime DateTime object specifying the end of the search period * (exclusive). * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static void printDateRangeQueryResults(BloggerService myService, DateTime startTime, DateTime endTime) throws ServiceException, IOException { // Create query and submit a request URL feedUrl = new URL(feedUri + POSTS_FEED_URI_SUFFIX); Query myQuery = new Query(feedUrl); myQuery.setUpdatedMin(startTime); myQuery.setUpdatedMax(endTime); Feed resultFeed = myService.query(myQuery, Feed.class); // Print the results System.out.println(resultFeed.getTitle().getPlainText() + " posts between " + startTime + " and " + endTime); for (int i = 0; i < resultFeed.getEntries().size(); i++) { Entry entry = resultFeed.getEntries().get(i); System.out.println("\t" + entry.getTitle().getPlainText()); System.out.println("\t" + entry.getUpdated().toStringRfc822()); } System.out.println(); } /** * Updates the title of the given post. The Entry object is updated with the * new title, then a request is sent to the GoogleService. If the insertion is * successful, the updated post will be returned. * * Note that other characteristics of the post can also be modified by * updating the values of the entry object before submitting the request. * * @param myService An authenticated GoogleService object. * @param entryToUpdate An Entry containing the post to update. * @param newTitle Text to use for the post's new title. * @return An Entry containing the newly-updated post. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static Entry updatePostTitle(BloggerService myService, Entry entryToUpdate, String newTitle) throws ServiceException, IOException { entryToUpdate.setTitle(new PlainTextConstruct(newTitle)); URL editUrl = new URL(entryToUpdate.getEditLink().getHref()); return myService.update(editUrl, entryToUpdate); } /** * Adds a comment to the specified post. First the comment feed's URI is built * using the given post ID. Then an Entry is created for the comment and * submitted to the GoogleService. * * NOTE: This functionality is not officially supported yet. * * @param myService An authenticated GoogleService object. * @param postId The ID of the post to comment on. * @param commentText Text to store in the comment. * @return An entry containing the newly-created comment. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If the URL is malformed. */ public static Entry createComment(BloggerService myService, String postId, String commentText) throws ServiceException, IOException { // Build the comment feed URI String commentsFeedUri = feedUri + "/" + postId + COMMENTS_FEED_URI_SUFFIX; URL feedUrl = new URL(commentsFeedUri); // Create a new entry for the comment and submit it to the GoogleService Entry myEntry = new Entry(); myEntry.setContent(new PlainTextConstruct(commentText)); return myService.insert(feedUrl, myEntry); } /** * Displays all the comments for the given post. First the comment feed's URI * is built using the given post ID. Then the method requests the comments * feed and displays the results. * * @param myService An authenticated GoogleService object. * @param postId The ID of the post to view comments on. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If there is an error communicating with the server. */ public static void printAllComments(BloggerService myService, String postId) throws ServiceException, IOException { // Build comment feed URI and request comments on the specified post String commentsFeedUri = feedUri + "/" + postId + COMMENTS_FEED_URI_SUFFIX; URL feedUrl = new URL(commentsFeedUri); Feed resultFeed = myService.getFeed(feedUrl, Feed.class); // Display the results System.out.println(resultFeed.getTitle().getPlainText()); for (int i = 0; i < resultFeed.getEntries().size(); i++) { Entry entry = resultFeed.getEntries().get(i); System.out.println("\t" + ((TextContent) entry.getContent()).getContent().getPlainText()); System.out.println("\t" + entry.getUpdated().toStringRfc822()); } System.out.println(); } /** * Removes the comment specified by the given editLinkHref. * * @param myService An authenticated GoogleService object. * @param editLinkHref The URI given for editing the comment. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If there is an error communicating with the server. */ public static void deleteComment(BloggerService myService, String editLinkHref) throws ServiceException, IOException { URL deleteUrl = new URL(editLinkHref); myService.delete(deleteUrl); } /** * Removes the post specified by the given editLinkHref. * * @param myService An authenticated GoogleService object. * @param editLinkHref The URI given for editing the post. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If there is an error communicating with the server. */ public static void deletePost(BloggerService myService, String editLinkHref) throws ServiceException, IOException { URL deleteUrl = new URL(editLinkHref); myService.delete(deleteUrl); } /** * Runs through all the examples using the given GoogleService instance. * * @param myService An authenticated GoogleService object. * @param userName username of user to authenticate (e.g. jdoe@gmail.com). * @param userPassword password to use for authentication. * @throws ServiceException If the service is unable to handle the request. * @throws IOException If there is an error communicating with the server. */ public static void run(BloggerService myService, String userName, String userPassword) throws ServiceException, IOException { // Authenticate using ClientLogin myService.setUserCredentials(userName, userPassword); // Get the blog ID from the metatfeed. String blogId = getBlogId(myService); feedUri = FEED_URI_BASE + "/" + blogId; // Demonstrate retrieving a list of the user's blogs. printUserBlogs(myService); // Demonstrate how to create a draft post. Entry draftPost = createPost(myService, "Snorkling in Aruba", "<p>We had so much fun snorkling in Aruba<p>", "Post author", userName, true); System.out.println("Successfully created draft post: " + draftPost.getTitle().getPlainText()); // Demonstrate how to publish a public post. Entry publicPost = createPost(myService, "Back from vacation", "<p>I didn't want to leave Aruba, but I ran out of money :(<p>", "Post author", userName, false); System.out.println("Successfully created public post: " + publicPost.getTitle().getPlainText()); // Demonstrate various feed queries. printAllPosts(myService); printDateRangeQueryResults(myService, DateTime.parseDate("2007-04-04"), DateTime.parseDate("2007-04-06")); // Demonstrate two ways of updating posts. draftPost.setTitle(new PlainTextConstruct("Swimming with the fish")); draftPost.update(); System.out.println("Post's new title is \"" + draftPost.getTitle().getPlainText() + "\".\n"); publicPost = updatePostTitle(myService, publicPost, "The party's over"); System.out.println("Post's new title is \"" + publicPost.getTitle().getPlainText() + "\".\n"); // Demonstrate how to add a comment on a post // Get the post ID and build the comments feed URI for the specified post System.out.println("Creating comment"); String selfLinkHref = publicPost.getSelfLink().getHref(); String[] tokens = selfLinkHref.split("/"); String postId = tokens[tokens.length - 1]; Entry comment = createComment(myService, postId, "Did you see any sharks?"); // Demonstrate how to retrieve the comments for a post printAllComments(myService, postId); // Demonstrate how to delete a comment from a post System.out.println("Deleting comment"); deleteComment(myService, comment.getEditLink().getHref()); // Demonstrate two ways of deleting posts. System.out.println("Deleting draft post"); draftPost.delete(); System.out.println("Deleting published post"); deletePost(myService, publicPost.getEditLink().getHref()); } /** * Uses the command line arguments to authenticate the GoogleService and build * the basic feed URI, then invokes all the other methods to demonstrate how * to interface with the Blogger service. * * @param args See the usage method. */ public static void main(String[] args) { // Set username, password and feed URI from command-line arguments. SimpleCommandLineParser parser = new SimpleCommandLineParser(args); String userName = parser.getValue("username", "user", "u"); String userPassword = parser.getValue("password", "pass", "p"); boolean help = parser.containsKey("help", "h"); if (help || (userName == null) || (userPassword == null)) { usage(); System.exit(1); } BloggerService myService = new BloggerService("exampleCo-exampleApp-1"); try { run(myService, userName, userPassword); } catch (ServiceException se) { se.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } } /** * Prints the command line usage of this sample application. */ private static void usage() { System.out.println("Usage: BloggerClient --username <username>" + " --password <password>"); System.out.println("\nA simple application that creates, queries,\n" + "updates and deletes posts and comments on the\n" + "specified blog using the provided username and\n" + "password for authentication."); } }