Publishing to Web Feeds Using the ROME Propono Client API
ROME Propono includes a high-level client API for connecting to a web feed and retrieving, creating, and modifying web entries. The com.sun.syndication.propono.blogclient package includes classes that simplify the process of working with web feeds.
Connecting to an Atom Server
The BlogConnection class represents a connection to a particular web feed for a particular user. New BlogConnection instances are retrieved by using the BlogConnectionFactory class's getBlogConnection method. The getBlogConnection method required four parameters: the type of feed, the URI of the feed, the username, and the password.
The following snippet shows how to use obtain an instance of the BlogConnection class by invoking BlogConnectionFactory.getBlogConnection.
BlogConnection blogConnection = BlogConnectionFactory.getBlogConnection("atom", feedUri, userName, password);
In this case, the web feed type is an Atom feed. BlogConnectionFactory also can connect to Metaweblog web feeds.
Working with a Web Feed
The Blog interface models a particular blog from a particular web feed. Blog instances are retrieved from a BlogConnection instance, and the implementing class is either an AtomBlog or MetaWeblogBlog depending on the type of the web feed specified when creating the BlogConnection instance .
The following snippet retrieves the first available blog from a BlogConnection instance.
Blog blog = (Blog) blogConnection.getBlogs().get(0);
Blog instances have collections of blog entries, resources (like images or media files), as well as categories. These collections are represented by Blog.Collection instances. Blog.Collection instances allow you to retrieve specific entries or resources, iterate over all the entries or resources in the collection, and create new entries or resources. Blog entries are represented by BlogEntry instances, and blog resources are represented by BlogResource instances.
The BlogEntry and BlogResourceInterfaces
The BlogEntry interface models a particular entry in a web feed, and has properties that correspond to authors, categories, content, status, and other metadata associated with a blog entry. The BlogResource interface is a sub-interface of BlogEntry, and represents a file that has been uploaded to a web feed. Typically, these are images, but BlogResource instances can be any type of file.
The Blog.Collection.newEntry method returns a new BlogEntry instance. The Blog.Collection.newResource method returns a new BlogResource instance. Both newEntry and newResource do not save the newly created entries or resources to the collection.
The BlogEntry.Content class represents the content of a blog entry. BlogEntry.Content instances have a properties that correspond to the type of the content (HTML, text, a MIME type) and the content itself. The default content type is HTML, but you can set it to text or another MIME type by invoking the BlogeEntry.Content.setType method.
The following snippet shows how to create a new BlogEntry instance and set the title and content of the new instance:
Blog entry = collection.newEntry(); BlogEntry.Content content = new BlogEntry.Content(); entry.setTitle("The title of a blog entry"); content.setType("text"); content.setValue("The body of a blog entry."); entry.setContent(content);
Adding Entries to a Web Feed
To add blog entries, do one of the following:
Pass the BlogEntry instance to the Blog.Collection.saveEntry method, which saves the entry and adds it to the collection.
Invoke the BlogEntry.save method on the instance.
To save resources, do one of the following:
Pass the BlogResource instance to the Blog.Collection.saveResource method, which saves the resource and adds it to the collection.
Invoke the BlogResource.save method in the instance.
The following snippet demonstrates a simple way to create and add entries to a collection.
BlogEntry entry = collection.newEntry(); BlogEntry.Content content = new BlogEntry.Content(); entry.setTitle("Title of a blog entry"); content.setValue("<p>This is some HTML content.</p>"); entry.setContent(content); entry.save();
Retrieving Entries from a Web Feed
The Blog.Collection.getEntries method returns a java.util.Iterator so you can iterate over all the entries and resources in a collection.
For example, the following snippet adds all the blog entries in a collection to a java.util.ArrayList:
List<BlogEntry> entries = new ArrayList<BlogEntry>(); Iterator<BlogeEntry> iterator = collection.getEntries(); while (iterator.hasNext()) { BlogEntry entry = iterator.next(); entries.add(entry); }
Creating, Retrieving, and Modifying Feeds in the atom-feed Example
The atom-feed example demonstrates how to create a simple Atom feed server that can authenticate a number of different users against a database using the Java Persistence API. It also has a JavaServer Faces client that allows you to create users, log in, create entries, and retrieve collections of entries.
Overview of atom-feed
The atom-feed example consists of an Atom server and a JavaServer Faces web application that allows you to add users that may then login and create Atom feeds.
The Atom Server
The Atom server component of atom-feed consists of AtomServerImpl, a class that extends GenericAtomHandlerImpl, and AtomServerFactory, a factory class for creating new instances of AtomServerImpl. Both of these classes were described above.
The AtomServlet is configured in the web.xml deployment descriptor to respond to requests of the following form:
http://server:server port/atom-feed/atom/*
The following snippet shows the servlet definition and URL pattern for AtomServlet:
<servlet> <description>AtomServlet which deals with Atom Publishing Protocol requests</description> <servlet-name>AtomServlet</servlet-name> <servlet-class>com.sun.syndication.atomprotocol.AtomServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AtomServlet</servlet-name> <url-pattern>/atom/*</url-pattern> </servlet-mapping>
The JavaServer Faces Front End
The JavaServer Faces web application consists of two parts:
a JSP page containing an input form, backed by a managed bean, UserBean. UserBean creates new Atom users and stores them in the underlying database by using the Java Persistence API. After the user creates a new Atom user, the user can then access the Atom server to create and modify Atom feeds.
JSP pages that work with a another managed bean, FeedBean. FeedBean connects users to Atom feeds, and creates and retrieves entries from the Atom feed.
The FeedBean Managed Bean
FeedBean has three business methods:
addEntry, which creates entries.
getEntries, which retrieves all the blog entries from a particular Atom feed.
getBlog, a convenience method for connecting to the user's Atom feed.
The following snippet shows the addEntry, getEntries, and getBlog methods.
public String addEntry() throws BlogClientException { // default status of JSF action String status = "failure"; if (this.userBean == null) { return "notloggedin"; } else { // get the username from the form userName = this.getUserBean().getUser().getLoginId(); // get the password from the form password = getUserBean().getUser().getPassword(); // call private method to open the connection to the blog URI blog = this.getBlog(userName, password); try { // Get the collection of entries collection = blog.getCollection(blog.getToken()); // create a new entry entry = collection.newEntry(); // get the entry title from the form String title = (String)this.getEntryTitleTextField().getValue(); if (entry == null) { logger.warning("Entry is null"); } // set the title and content of the entry entry.setTitle(title); entry.setContent(new BlogEntry.Content( (String)this.getEntryContentTextarea().getValue())); // save the entry entry.save(); // set the return status for the JSF navigation rules status = "success"; } catch (BlogClientException ex) { ex.printStackTrace(); } } return status; } public List<BlogEntry> getEntries() throws BlogClientException, UserNotLoggedInException { if (this.userBean == null) { this.message = "User not logged in"; throw new UserNotLoggedInException("User must be logged in."); } userName = this.getUserBean().getUser().getLoginId(); password = getUserBean().getUser().getPassword(); blog = this.getBlog(userName, password); try { collection = blog.getCollection(blog.getToken()); entryIterator = collection.getEntries(); while (entryIterator.hasNext()) { BlogEntry entry = entryIterator.next(); logger.info("Entry title is " + entry.getTitle()); entries.add(entry); } } catch (BlogClientException ex) { ex.printStackTrace(); } return entries; } ... // private convenience method to make connection to blog URI with supplied // username and password private Blog getBlog(String userName, String password) { try { // get the connection to the Atom feed URI blogConnection = BlogConnectionFactory.getBlogConnection("atom", feedUri, userName, password); } catch (BlogClientException ex) { ex.printStackTrace(); } // get the first blog that accepts entries return (Blog) blogConnection.getBlogs().get(0); }