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