Hi,

While the new REST client will be very good at working with REST API's exposed by the REST server library, I thought it would be fun to try it with something more general, like RSS feeds.

The below code will parse my blog RSS feed, and for each entry looks up the comments and prints them as well. All of it is done with a workflow/statemachine type of thinking. The trickiest part is how to do decent continuation of flow, as you would do with imperative programming. Code is as follows:
crc.onResource( new ResultHandler<Document>()
{
    Iterator<Node> itemNodes;

    @Override
public HandlerCommand handleResult( Document result, ContextResourceClient client )
    {
        try
        {
            final XPath xPath = XPathFactory.newInstance().newXPath();

System.out.println( "== "+xPath.evaluate( "rss/channel/title", result )+" ==");

final NodeList nodes = (NodeList)xPath.evaluate( "rss/channel/item", result, XPathConstants.NODESET);
            List<Node> items = new ArrayList<Node>();
            for (int i = 0; i < nodes.getLength(); i++)
                items.add( nodes.item( i ) );

            itemNodes = items.iterator();

            return processEntry( xPath );
        }
        catch( XPathExpressionException e )
        {
            throw new ResourceException( e );
        }
    }

    private HandlerCommand processEntry( final XPath xPath )
        throws XPathExpressionException
    {
        if (!itemNodes.hasNext())
            return null;

        Node item = itemNodes.next();

        System.out.println( "-- "+xPath.evaluate( "title", item )+" --" );
        String commentUrl = xPath.evaluate( "commentRss", item );

        ValueBuilder<Link> link = module.newValueBuilder( Link.class );
        link.prototype().rel().set( "item" );
        link.prototype().id().set( "item" );
        link.prototype().href().set( commentUrl );

return query( link.newInstance() ).onSuccess( new ResultHandler<Document>()
            {
                @Override
public HandlerCommand handleResult( Document result, ContextResourceClient client )
                {
                    try
                    {
final NodeList comments = (NodeList)xPath.evaluate( "rss/channel/item", result, XPathConstants.NODESET);
                        for (int i = 0; i < comments.getLength(); i++)
                        {
System.out.println( xPath.evaluate( "description", comments.item( i ) ));
                            System.out.println( "---");
                        }

                        return processEntry( xPath );
                    }
                    catch( XPathExpressionException e )
                    {
                        throw new ResourceException( e );
                    }
                }
            } );
    }
} );

crc.start();
---
So once the workflow is setup and started, it will first find the feed and convert it to a XML Document (converter omitted in the above code). I then use XPath to find the elements I'm interested in, and continue with queries that follow the links. The "processEntry" helper method was introduced because otherwise some code would be duplicated in the main handleResult and onSuccess handleResult methods.

If there are any errors on the way, they can be handled automatically. Any redirects can be followed automatically as well to allow for server changes that have occurred.

You can find the full code in RssReaderTest in the REST-client library in Git.

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to