sun.com docs.sun.com My Sun Worldwide Sites

  Previous Contents Next
Chapter 7

Working With Web Feeds Using ROME Propono

Describes how to use the ROME Propono APIs for creating, organizing, and deleting Atom feeds.

Understanding Web Feeds

This section describes how web feeds work.

The Atom Syndication Format (hereafter Atom format) is an XML language for representing web feeds. A web feed is a collection of information, like articles, blog entries, or media files that is made available via a Universal Resource Identifier to clients. These clients read the XML returned by requests to the web feed's URI, and can then display, modify, or delete the entries contained in the feed.

The Atom Publishing Protocol (henceforth the Atom protocol) is an HTTP-based protocol for accessing and modifying web feeds in the Atom format.

The ROME Propono API

The ROME Propono API is a Java programming language implementation of the Atom protocol version 1.0. Its API allows you to create, retrieve, modify, and delete web feeds in Atom and RSS formats. The framework hides many of the implementation details of working with web feeds, entries, and collections, making it easier for developers to integrate web feeds into their applications.

ROME Propono Architecture

Applications that use the Propono API are standard Java EE web applications configured to use AtomServlet, which acts as the controller for responding to requests for Atom feeds, collections, and entries. AtomServlet delegates the incoming requests to an AtomHandler instance. The handler is responsible for authentication and responding to the HTTP requests (GET, POST, PUT, DELETE) for a particular feed.

The four HTTP request methods correspond to actions a user can take on an Atom feed. The following table lists the HTTP method and corresponding action.

Table 7-1 HTTP Request Methods and ROME Propono Actions

HTTP Method

Action

GET

Retrieve a feed, collection, or entry.

POST

Create a collection or entry.

PUT

Modify a collection or entry.

DELETE

Remove a collection or entry.

The handler is responsible for authenticating the user before any requests can be processed.

Creating a Web Feed Using the ROME Propono API

The ROME Propono API simplifies the process of creating and customizing how web feeds are generated, modified, distributed.

The AtomHandler Interface

The AtomHandler interface defines the basic behavior of an Atom feed server. It defines methods to create, modify, and delete web feed entries, as well as return web feeds. Developers implement the AtomHandler interface to customize how a particular web feed server should perform these actions.

The Atom Server Framework provides a default implementation of AtomHandler, FileBasedAtomHandlerImpl to demonstrate how a basic Atom feed server operates. Individual entries are stored in files on the server, and users are authenticated using HTTP Basic authentication. Developers may extend FileBasedAtomHandler to customize their handler.

The following code shows the AtomServerImpl class, which extends FileBasedAtomHandler.

public class AtomServerImpl extends FileBasedAtomHandler {
    
    private static final Logger logger = Logger.getLogger("AtomServerImpl");
    
    private AtomUser user;
    
    /**
     * Creates a new instance of AtomServerImpl
     */
    public AtomServerImpl( HttpServletRequest request ) {
        super(request);
    }
    
    public boolean validateUser(String loginId, String password) {
        logger.info("validateUser login: " + loginId);
        
        user = this.lookupUser(loginId);
        if (user == null) {
            logger.info("validateUser no such user: " + loginId);
            return false;
        } else if (password.equals(user.getPassword())) {
            logger.info("validateUser password accepted for " + loginId);
            return true;
        } else {
            logger.info("validateUser password doesn't match for " + loginId);
            return false;
        }
    }

    private void persist(Object object) {
        try {
            Context ctx = new InitialContext();
            EntityManager em =  (EntityManager) 
					ctx.lookup("java:comp/env/persistence/atom-feed");
            UserTransaction utx = (UserTransaction) 
					ctx.lookup("java:comp/env/UserTransaction");
            utx.begin();
            em.persist(object);
				 utx.commit();
        } catch(Exception e) {
            logger.log(Level.SEVERE,"exception caught", e);
            throw new RuntimeException(e);
        }
    }
    
    private AtomUser lookupUser(String loginId) {
        logger.info("lookupUser looking up: " + loginId);
        AtomUser atomUser = null;
        try {
            Context ctx = new InitialContext();
            EntityManager em =  (EntityManager) 
					ctx.lookup("java:comp/env/persistence/atom-feedPU");
            atomUser = (AtomUser) em.createNamedQuery("findAtomUserByLoginName").
                setParameter("loginId", loginId).
                getSingleResult();
        } catch (Exception e) {
            logger.log(Level.SEVERE,"exception caught", e);
        }
        return atomUser;
    }
}

In AtomServerImpl, the user is authenticated by retrieving the user ID and password from a database by using the Java Persistence API and comparing the values with the values submitted via HTTP Basic authentication. AtomUser is a Persistence entity which stores the login ID and unencrypted password in the underlying data source.


Note - In a production environment, the password should not be stored in plain text in the database, but for simplicity we are not storing encrypted passwords.


The AtomHandlerFactory Class

The AtomHandlerFactory class provides a factory API for creating new handler instances. The AtomServlet uses this API to create handler instances and then delegates the requests to the handler instances created by AtomHandlerFactory. New handler instances are created when the newInstance method is called from AtomServlet. The method uses the following procedure to find new handler instances:

  1. Use the com.sun.syndication.propono.atom.server.AtomHandlerFactory system property, if set.

  2. Use the propono.properties file in the classpath of the WAR to find the factory, looking for the com.sun.syndication.propono.atom.server.AtomHandlerFactory property.

    If propono.properties doesn't exist when the first handler request is received, the runtime will not look for it on subsequent requests.

  3. The runtime will then look for the class in the following location in JARs available to the runtime:

    META-INF/services/com.sun.syndication.propono.atom.server.AtomHandlerFactory
  4. If no handler factory can be found, use the runtime's default AtomHandlerFactory instance. The default factory handler in the Sun Web Developer Pack is FileBasedAtomHandlerFactory.

Developers extend AtomHandlerFactory and override the newAtomHandler method to return an instance of an AtomHandler.

The following code shows how to extend the AtomHandlerFactory and override the newAtomHandler method.

public class AtomServerFactory extends AtomHandlerFactory {

    public static final Logger logger = Logger.getLogger("AtomServerFactory");

    public AtomHandler newAtomHandler (HttpServletRequest request) {
        logger.info("newAtomHandler: creating AtomServer.");
        return new AtomServerImpl(request);
    }

}
Previous Contents Next
Company Info Contact Terms of Use Privacy Copyright 1994-2007 Sun Microsystems, Inc.