Background (being delisted from Javablogs)
PaulHammant.com was thrown off Javablogs.com for having one too many
non-Java postings. Mike Cannon-Brookes forced me to sink an 'Irish car
bomb' (with about 20 others) on Tuesday in matter of seconds and
provide a second RSS feed to get listed again. I earn about 50c a month
from Google ads. It's a pretty important supplement to a paultry
ThoughtWorks wage...
Given I stupidly hand edit this blog, I thought I'd try a little
automation. That would mean something that could create a second
RSS feed that would only contain Java related blog entries. The
most recent work to XStream allows XML attributes to be used as well as
emelemnts for encoding. RSS does not leverage a lot of attributes (it's
quite element normal), but there is one key one - <rss
version="x.y"> - that needs the latest changes to XStream to
function.
POJOs for RSS
Here are is the core Java POJO classes that cover the major elements of RSS 0.91
public class Rss {
Version version;
Channel channel;
}
public class Channel {
String title, link, description, language, webMaster, pubDate;
List items = new ArrayList();
}
public class Item {
String title, link, description;
}
The version attribute on the root <rss> element needs a special class...
public class Version {
private String value;
public Version(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
... and a special converter to link it up:
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
public class VersionConverter extends AbstractSingleValueConverter {
public boolean canConvert(Class type) {
return type.equals(Version.class);
}
public String toString(Object obj) {
return obj == null ? null : ((Version) obj).getValue();
}
public Object fromString(String str) {
return new Version(str);
}
}
And here's the final helper class to do the conversion from/to RSS document to an object model:
public class RssConverter {
private XStream xs;
public RssConverter(XStream xs) {
this.xs = xs;
xs.alias("rss", Rss.class);
xs.alias("item", Item.class);
xs.addImplicitCollection(Channel.class, "items");
xs.useAttributeFor("version", Version.class);
xs.registerConverter(new VersionConverter());
}
public RssConverter() {
this(new XStream(new DomDriver()));
}
public Rss fromXml(FileInputStream fileInputStream) {
return (Rss) xs.fromXML(fileInputStream);
}
public void toXml(Rss rss, OutputStream stream) {
xs.toXML(rss, stream);
}
}
And using it...
FileInputStream fis = new FileInputStream("../blog/index.xml");
RssConverter converter = new RssConverter();
Rss rss = converter.fromXml(fis);
...
converter.toXML(rss, new FileOutputStream("../blog/java-index.xml"));
I'll speak to Joe, Mauro and Jörg about a comprehensive RSS class
model in the XStream project. If anyone is interested in contributing
(unit tested) code then send me an email.
Other XML forms
Actually, I'd love to see as many 'standard' XML forms tackled as
possible. XStream is should be able to cope with most of the simple XML
based standards.
For example. RSS's competitor Atom looks like quite an easy job for XStream. See
http://en.wikipedia.org/wiki/Atom_(standard)
Others like ebXml, XSL, XUL etc do not look so encodable. See
http://www.perfectxml.com/XMLAcronyms.asp