diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7075a2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/target
+/.classpath
+/.project
+/.settings
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2013f17
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+rome
+====
+
+ROME is a set of RSS and Atom Utilities for Java. It makes it easy to work in Java with most syndication formats: RSS 0.90, RSS 0.91 Netscape, RSS 0.91 Userland, RSS 0.92, RSS 0.93, RSS 0.94, RSS 1.0, RSS 2.0, Atom 0.3, Atom 1.0
+
+More Information: http://rometools.github.io/rome/
diff --git a/pom.xml b/pom.xml
index 216dcc3..a5c13a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,9 +15,9 @@
SyndFeed object that lets you work on with the data without bothering about the
underlying format.
- https://rome.dev.java.net/
+ http://rometools.github.io/rome/
- https://rometools.jira.com/browse/ROME#selectedTab=com.atlassian.jira.plugin.system.project%3Aissues-panel
+ https://github.com/rometools/rome/issues
@@ -32,15 +32,9 @@
dev@rome.dev.java.net
-
- https://rome.dev.java.net/servlets/ProjectMailingListList
-
-
- https://rome.dev.java.net/servlets/ProjectMailingListList
-
-
- https://rome.dev.java.net/servlets/SummarizeList?listName=dev
-
+ https://rome.dev.java.net/servlets/ProjectMailingListList
+ https://rome.dev.java.net/servlets/ProjectMailingListList
+ https://rome.dev.java.net/servlets/SummarizeList?listName=dev
@@ -66,9 +60,9 @@
- scm:svn:https://rometools.jira.com/svn/ROME/trunk
- scm:svn:https://rometools.jira.com/svn/ROME/trunk
- https://rometools.jira.com/source/browse/ROME
+ scm:git:git@github.com:rometools/rome.git
+ scm:git:git@github.com:rometools/rome.git
+ https://github.com/rometools/rome
@@ -123,11 +117,42 @@
org.apache.maven.pluginsmaven-resources-plugin
- 2.2
+ 2.6${project.build.sourceEncoding}
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 3.3
+
+ 9000
+ ${basedir}/target/site/tempdir
+
+
+
+ org.apache.maven.doxia
+ doxia-module-markdown
+ 1.4
+
+
+ org.apache.maven.doxia
+ doxia-module-confluence
+ 1.4
+
+
+
+
+ org.apache.maven.plugins
+ maven-scm-publish-plugin
+ 1.0-beta-2
+
+ gh-pages
+ scm:git:git@github.com:rometools/rome.git
+ ${project.build.directory}/site
+
+
@@ -197,5 +222,33 @@
UTF-8
-
+
+
+
+ org.apache.maven.plugins
+ maven-project-info-reports-plugin
+ 2.6
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.9
+
+
+
+ javadoc
+ test-javadoc
+
+
+
+ aggregate
+ false
+
+ aggregate
+
+
+
+
+
+
diff --git a/src/site/apt/ChangeLog.apt b/src/site/apt/ChangeLog.apt
new file mode 100644
index 0000000..2b19e97
--- /dev/null
+++ b/src/site/apt/ChangeLog.apt
@@ -0,0 +1,773 @@
+ -----
+ Change Log
+ -----
+ mkurz
+ -----
+ 2011-08-15 06:19:27.183
+ -----
+
+Change Log
+
+
+*Changes made since v1.0
+
+
+
+ [[1]] {{{http://java.net/jira/browse/ROME\-127}Issue 127}}: Rome 1.0 not JDK 1.4 compatible
+
+ []
+
+*Changes made since v1.0RC2
+
+
+
+ [[1]] {{{http://java.net/jira/browse/ROME\-121}Issue 121}}: RSS item category iteration should try to reflect document order
+
+ [[1]] New property preserveWireFeed available on SyndFeedInput\
+ WireFeeds will be preserved if the property preserveWireFeed is set on the SyndFeedInput object it is built from. Atom/RSS Entry/Item objects are also available from SyndEntry objects if the WireFeed is preserved using the new getWireEntry() method. See {{{./PreservingWireFeeds.html}Preserving WireFeeds (rome)}} for details.
+
+ []
+
+*Changes made since v1.0RC1
+
+
+
+ [[1]] Fix. Date parsing for Atom10 entry and additional W3C masks\
+ Item date elements were being parsed with the W3C parser instead the lenient one (RFC822 \+ W3C \+ custom masks).\
+ The following masks were added to W3C masks to handle RFC822 timezone (ie '\-800'):
+
++------+
+
+yyyy-MM-dd'T'HH:mm:ssZ yyyy-MM-dd't'HH:mm:sszZ
+
++------+
+
+
+ [[1]] Fix. Contributors properties in SyndEntry were not implementing the semantics of list properties.\
+ They were returning NULL instead, now they return an empty list if not values are set.
+
+ [[1]] Fix. Contributors properties in SyndEntry and SyndFeed were not being converted to/from WireFeed
+
+ [[1]] Fix. Syndication Module Generator was failing if some of its values were null.\
+ Checks for nulll have been added it to the generator to prevent NullPointerExceptions
+
+ [[1]] New. Added new constructor to XmlReader
+
++------+
+
+public XmlReader(InputStream is, boolean lenient, String defaultEncoding)
+
++------+
+
+
+ [[1]] New. Support atom person construct extensions, using the Extendable interface on SyndPerson:\
+ Patch from James Roper. See {{{http://java.net/jira/browse/ROME\-110}Issue 1101}} for details
+
+ [[1]] New. Maven 2 build for main project\
+ ROME can now be built with Maven 2
+
+ [[1]] New. OSGi support\
+ OSGi headers to MANIFEST.MF so that rome.jar can also be used in an OSGi environment. See {{{http://java.net/jira/browse/ROME\-117}Issue 117}} for details.
+
+ [[1]] New. Allow pretty printing to be turned on and off\
+ see {{{http://java.net/jira/browse/ROME\-114}Issue 114}} for details. Thanks to Martin Kurz for the patch.
+
+ [[1]] Configurable classloading behavior for OSGi compatibility.\
+ We have received a report of some issues with plugin loading in an OSGi environment ({{{http://java.net/jira/browse/ROME\-118}Issue 118}}). The fix appears to be to change Class.forName to classLoader.loadClass, but the semantics for this are subtly different, so we have made this new behavior user selectable. Set the "rome.pluginmanager.useloadclass" system property to "true" to enable it.
+
+ [[1]] More lenient number parsing\
+ There were a number of problems with feeds providing blank or invalid values in fields which would be numbers. ROME will now handles these better. See issues {{{http://java.net/jira/browse/ROME\-104}104}}, {{{http://java.net/jira/browse/ROME\-107}107}} and {{{http://java.net/jira/browse/ROME\-108}108}} for details.
+
+ []
+
+*Changes made from v0.9 to v1.0RC1
+
+
+
+ [[1]] New. XmlReader support for default encoding\
+ The XmlReader can be set with an alternate default encoding in case no encoding has been detected from the transport (HTTP), the stream or the XML prolog. if no value is set the default fallback rules based on the content\-type will be used. The alternate default encoding can be set/viewed via a static methods, <> and <>.
+
+ [[1]] Fix. Atom 1.0 links were generated without title and length attributes.\
+ The Atom 1.0 Generator was not generating title and length attributes when values are present.
+
+ [[1]] Fix. XmlReader, multi\-line prolog encoding detection.\
+ XmlReader handles properly xml\-prolog detection when prolog goes over multiple lies (such as G groups feeds).
+
+ [[1]] Fix. Base64 decoding was failing under certain padding conditions.
+
+ [[1]] Fix. XmlReader fixes\
+ Fixed bug that if BOM is UTF8 was not being set to UTF8. Changed logic to use Buffered stream instead pushback stream for all encoding detection. Changed logic of xml prolog detection to avoid having a buffer with half of a unicode character (instead filling up the buffer looking up to first '\>' which means it a valid buffer).
+
+ [[1]] New. XmlReader supports default encoding at instance level.\
+ Via a new constructor is possible to indicate a default encoding different than the default encoding at class level.
+
+ [[1]] Fix. Making the EqualsBean to follow equals contract.\
+ For X.equals(null) it was throwing a NullPointerException, now it returns FALSE.
+
+ [[1]] Fix. Render Atom icon and logo attributes.\
+ AtomGenerator now adds icon and logo elements to xml tree
+
+ [[1]] Fix. Updated AtomPub namespace to its permenent home.\
+ AtomService namespace updated to {{{http://www.w3.org/2007/app}http://www.w3.org/2007/app}}
+
+ [[1]] New. Added support for configuration per classloader level.\
+ The PluginManager (handles Parsers and Generators) now is singleton at classloader level allowing different configurations in different classloaders.
+
+ [[1]] Atom parser: better relative URI handling\
+ Instead of simply resolving each relative URI at runtime and saving only the resolved one, we now save both the relative URI and the resolve one. We introduced the following new methods to provide access to the resolved URI.
+
+ * Link.getLinkResolved()
+
+ * Link.setLinkResolved()
+
+ * Category.getSchemeResolved()
+
+ * Category.setSchemeResolved()
+
+ * Person.getUriResolved()
+
+ * Person.setUriResolved()
+
+
+
+ [[1]] Utility methods useful in working with Atom protocol feeds\
+ Added a couple of methods to make it easier to deal with Atompub feeds.
+
+ * Entry.isMediaEntry()
+
+ * Atom10Parser.parseEntry()
+
+ * Atom10Generator.serializeEntry()
+
+
+
+ [[1]] Bugs fixed\
+ Fixed the following bugs:
+
+ * 49 Better content/summary mapping
+
+ * 53 Content.setType not working with subtitles atom 1.0
+
+ * 56 fix of bug #39 leads to invalid atom feeds
+
+ * 63 Missing link attribute when generating Atom 1.0
+
+ * 64 ROME's Atom parser doesn't pick up multiple alt links
+
+ * 65 Atom feeds not including logo image
+
+ * 71 encoding problem in XmlReader.getXmlProlog()
+
+ * 79 Feed.setIcon()/setLogo() ignored by Atom10Generator
+
+ * 81 SyndFeedImpl.equals() does not obey equals contract
+
+
+
+ [[1]] Fix. Parsers where ignoring namespaced prefixed Attributes.\
+ If an XML feed uses a prefix for the Atom elements and the attributes of Atom elements use the prefix the parser was not picking up those attributes.\
+ The fix makes the parser to look for prefixed and non\-prefixed attributes.
+
+ [[1]] Fix. Atom Feed and Entry beans author and category property getters\
+ They were returning NULL when there were not authors or categories, they must return an empty list.
+
+ [[1]] New. Switch to enable/disable relative URI resolution in Atom 1.0 Parser.\
+ The Atom10Parser class has a static method, setResolveURIs(boolean) that enables/disables relative URI resolution.
+
+ [[1]] New. XmlReader handling content\-type charset values has been relaxed.\
+ XmlReader handles content\-type charset encoding value within single quotes and double quotes.
+
+ [[1]] Fix. Links, authors and contributors properties in SyndFeed were not implementing the semantics of list properties.\
+ They were returning NULL instead, now they return an empty list if not values are set.
+
+ [[1]] Fix. RSS conversion of a SyndFeed was losing the link of the feed if the links property was used instead the link property.\
+ Over time the SyndFeed has been modified to support more Atom specific properties and their cardinality, conversion to RSS of these properties was not always taken care.\
+ The RSS converter has been changed so the link from SyndFeed is taken as channel link and if not set the first value of the links property is taken.
+
+ [[1]] Fix. WireFeedInput throws IllegalArgumentException if the feed type is not recognized.\
+ Previously the IllegalArgumentException was wrapped by a ParsingFeedException (Reported by {{{http://java.net/jira/browse/ROME\-91}Issue 91}}).
+
+ [[1]] Fix. SyndFeedImpl.equals(other) checks for instance of other before casting.\
+ The underlying ObjectBean does this check, but in this method a cast is done before to obtain the foreign markup, no the instance check is peformed before to avoid a class cast exception.
+
+ [[1]] Fix. Atom content based elements related fixes
+
+ * Atom 0.3 Parser/Generator
+
+ * Changed title to be treated as a Content construct. ({{{http://www.mnot.net/drafts/draft\-nottingham\-atom\-format\-02.html#rfc.section.4.3}http://www.mnot.net/drafts/draft\-nottingham\-atom\-format\-02.html#rfc.section.4.3}})
+
+
+
+ * Atom 1.0 Generator:
+
+ * changed feed title/subtitle and entry title to be treated as Content constructs. (Parser had this implemented already.)
+
+ * added title attribute to links. (Parser had this implemented already.)
+
+ * fixed content parsing for some XML content types. e.g. (application/xhtml\+xml)
+
+
+
+
+
+ [[1]] Fix. Atom link and enclosures handling
+
+ * Atom 0.3 Converter
+
+ * fixed link parsing code to parse all links (not just the first alternate link) and added enclosure support via link rel\="enclosure".
+
+ * changed title conversion to use Content instead of plain text.
+
+
+
+ * Atom 1.0 Converter
+
+ * added SyndEnclosure to atom:link rel\=enclosure conversion.
+
+
+
+
+
+ [[1]] Fix. RSS 1.0 URI generation
+
+ * RSS 1.0 Generator
+
+ * channel/items/Seq/li/@resource now get's the item URI instead of the Link. ({{{http://web.resource.org/rss/1.0/spec#s5.3.5}http://web.resource.org/rss/1.0/spec#s5.3.5}})
+
+
+
+
+
+ [[1]] Fix. Javadocs corrections.
+
+ * Fixed some javadoc comments for SyndEntry.
+
+
+
+ [[1]] Fix. Atom content based elements were not parsed with XML mime types.\
+ If the mime type was and XML mime type the content value was being lost on parsing.
+
+ [[1]] Fix. duplication of content:encoded elements when reading/writing and RSS feed.\
+ content:encoded elements are treated special, without a module, they have to be removed from the foreign markup to avoid duplication in case of read/write. Note that this fix will break if a content module is used.
+
+ [[1]] New. XmlFixerReader converts '&' into '&' when there is no matching entity.\
+ Feeds commonly use '&' instead '&' in their content, this change converts those orphant '&'s into '&'s.
+
+ [[1]] Fix. RSS090Parser does not set the URI property.\
+ The fix honors the documentation "For RSS 0.91, RSS 0.92, RSS 0.93 & RSS 1.0 ... the SyndEntry uri property will be set with the value of the link element..."
+
+ [[1]] New. Removal of all unused namespaces from generated feeds.\
+ The generators now remove all unused namespaces from the XML document before generating it.
+
+ []
+
+*Changes made from v0.8 to v0.9
+
+
+
+ [[1]] Design changes
+
+ * Support Atom feed.title, feed.subtitle and entry.title {{{http://java.net/jira/browse/ROME\-48}Issue 48}}\
+ #48 fixed via better support for Atom text constructs title and subtitle. Added get/setTitleEx() and get/setSubtitleEx(), which get get SyndContent objects. Title and subtitle still available from old getters/setters.
+
+ * Support for mapping Atom summary/content to RSS description/content {{{https://rome.dev.java.net/servlets/ReadMsg?list\=dev&msgNo\=1680}https://rome.dev.java.net/servlets/ReadMsg?list\=dev&msgNo\=1680}}
+
+ * Fixed by introduced Content object in RSS model. ROME now parses as RSS Content. That makes parsing easier and allows us to support a more logical summary/content mapping:
+
+ * RSS to/from Atom
+
+ * RSS to/from Atom
+
+
+
+
+
+ [[1]] General parsing fixes
+
+ * XmlReader xml prolog regular expression does not allow for single quotes {{{http://java.net/jira/browse/ROME\-36}Issue 36}}\
+ The XmlReader was only parsing prolog encodings within double quotes, the regular expression to detect the encoding has been change to detect single or double quotes.
+
+ * Fix. XML prolog parsing now support whitespaces around '\='\
+ If the XML prolog contained spaces around the '\=' between the encoding attribute name and the encoding attribute value the encoding was not being detected. The fix accepts all valid whitespace characters (as defined in the XML spec).
+
+ * RSS parser does not recognize version\="2.00" {{{http://java.net/jira/browse/ROME\-33}Issue 33}}
+
+ * Atom 1.0 Text Types Not Set Correctly {{{http://java.net/jira/browse/ROME\-39}Issue 39}}
+
+ * Security issue {{{http://java.net/jira/browse/ROME\-46}Issue 46}}
+
+ * Fix for the potential problem outlined in {{{http://www.securiteam.com/securitynews/6D0100A5PU.html}http://www.securiteam.com/securitynews/6D0100A5PU.html}}. Thanks to Nelson Minar for bringing this to our attention.
+
+ * Fix. Wrong default description type for RSS 2.0 Fix for {{{http://java.net/jira/browse/ROME\-26}Issue 26}}
+
+ * Change default description type for RSS 2.0 from text/plain to text/html as per RSS 2.0 spec
+
+ * Fix to add all HTML4 entities, according to {{{http://www.w3.org/TR/REC\-html40/sgml/entities.html}http://www.w3.org/TR/REC\-html40/sgml/entities.html}} specially for the HTMLsymbol set (Mathematical, Greek and Symbolic characters for HTML) and the HTMLspecial set (Special characters for HTML).
+
+
+
+ [[1]] Date parsing fixes
+
+ * Additional version and date leniency could extract more information {{{http://java.net/jira/browse/ROME\-24}Issue 24}}
+
+ * Non RFC822 Dates not processed in RSS pubDate field {{{http://java.net/jira/browse/ROME\-27}Issue 27}}
+
+ * RSS feed parsers were were only parsing RFC822 dates because they were not using the proper date\-time parsing function for the date\-time elements.
+
+ * If a W3C date\-time element had no time component it was being parsed as local time instead of GMT, ROME DateParser class has been modified to use GMT in this situation.
+
+ * Current JDKs do not handle 'UT' timezone indicator, ROME DateParser class has been modified to handle it.
+
+ * Use Atom updated instead of published {{{http://java.net/jira/browse/ROME\-41}Issue 41}}
+
+ * Atom 1.0 Date (Updated or Published) Not Set {{{http://java.net/jira/browse/ROME\-42}Issue 42}}
+
+ * lastBuildDate does not populate publishedDate {{{http://java.net/jira/browse/ROME\-43}Issue 43}} Provides a feed date for RSS 0.91 feeds that specify lastBuildDate but not pubDate.
+
+
+
+ * Fix. Parsing some numeric elements was failing due to whitespaces The image.width and image.height of RSS091U, the frequency of SyModule and the cloud.port of RSS092 elements are now being trimmed before doing the integer parsing.
+
+
+
+ [[1]] Atom link and URI fixes
+
+ * Improper relative link resolution in Atom10Parser {{{http://java.net/jira/browse/ROME\-37}Issue 37}}
+
+ * ATOM 1.0 Entry links parsing {{{http://java.net/jira/browse/ROME\-38}Issue 38}}
+
+ * ConverterForRSS10.java does not set URI for item {{{http://java.net/jira/browse/ROME\-25}Issue 25}}
+
+ * Valid IRI href attributes are stripped for atom:link {{{http://java.net/jira/browse/ROME\-34}Issue 34}}
+
+
+
+ [[1]] Module fixes
+
+ * iTunes Module has incorrect author and category support {{{http://java.net/jira/browse/ROME\-35}Issue 35}}
+
+ * mediarss.io.MediaModuleParser NumberFormatException {{{http://java.net/jira/browse/ROME\-45}Issue 45}}
+
+ * Slash module not serializable for FeedFetcher {{{http://java.net/jira/browse/ROME\-44}Issue 44}}
+
+
+
+ []
+
+*Changes made from v0.7 to v0.8
+
+
+
+ [[1]] Change. Added enclosure support at Synd\* level\
+ A new bean for handling enclosures at Synd\* level has been created (SyndEnclosure/SyndEnclosureImpl, interface/implementation).\
+ The SyndEntry/SyndEntryImpl bean has a new 'enclosures' property which returns the list of enclosures for that item.\
+ The Wire\* to Synd\* converters for RSS propagate enclosures in both directions.\
+ This enables handling enclosures from RSS 0.92, 0.93, 0.94 and 2.0 at Synd\* level\
+ Test cases have been modified to cover enclosures at Synd\* level.
+
+ [[1]] Change/Fix. Synd\* \- Atom entry dates mapping
+
+ * (Change) Atom entries have 3 dates, 'modified', 'issued' and 'created'. Synd entries have only 1 date property 'publishedDate'. When converting from Atom to Synd the first not null date in the order above will be the one set in the Synd entry bean.
+
+ * (Fix) When converting from Synd to Atom the Synd entries 'publishedDate' property value is set in both 'modified' and 'issued' properties of the Atom entry.\
+ This Change/Fix is to be aligned with the Atom 0.3 spec.
+
+
+
+ [[1]] Fix. Trim enclosure length attribute\
+ Fix from Trey Drake: At least 1 podcast site (ESPN) occasionally leaves trailing spaces in the enclosure content length attribute. This causes a NumberFormatException.
+
+ [[1]] Fix. Conversion to RSS 1.0 if Channel URI is not specified\
+ Fix for problem converting to RSS 1.0 if not URI is specified at the channel level (it will now attempt to use the Link element)
+
+ [[1]] Changes to support Atom 1.0
+
+ * In com.sun.syndication.synd, added SyndLink and SyndPerson.
+
+ * In SyndEntry added. In SyndEntry, added summary, updatedDate, links collection and support for multiple authors.
+
+ * In com.sun.syndication.synd.impl, added Atom10Parser.java, Atom10Generator.java and ConverterForAtom10.java.
+
+
+
+ []
+
+*Changes made from v0.6 to v0.7
+
+
+
+ [[1]] Fix. RFC\-882 dates parsing and generation were using localized names for day and month names\
+ The date parser and generator were using the JVM default Locale instead forcing an English Locale to use day and month names in English as specified by RFC\-822. Now US Locale is used.
+
+ [[1]] Fix. The 'ttl' element of RSS0.94 and RSS2.0 feeds was not being parsed\
+ The parsers now parse the 'ttl' element and it is available in the resulting Channel bean. Note that 'ttl' info is not available in the SyndFeed bean, thus it's lost when converting from WireFeed to SyndFeed.
+
+ [[1]] Change. RSS enclosures with empty 'length' attributes are accepted\
+ Parsing an RSS feed with an enclosure where the length attribute was an empty String were failing. Now they are parsed and the length is set to 0.
+
+ [[1]] Change. RSS 1.0 feeds use URI/Link for unique ID (rdf:about).\
+ RSS 1.0 specification recommends that the rdf:about attribute URI use the value of the item's link element, though this could be different if the user chooses to override it by specifying their own URI. RSS 1.0 feeds now use the URI if specified, otherwise the link for the item.
+
+ [[1]] Fix. toString() was reporting NullPointerException with List properties\
+ When a List (or Map) property had a NULL element the toString() logic was failing partially due to a NullPointerException.
+
+ [[1]] Fix. DC creator elements were being lost when converting to SyndFeed\
+ DC creator elements were being lost when converting to SyndFeed. This was happening with RSS versions that have native author elements (0.94 and 2.0) and for the managingEditor element at channel level (available in 0.91 Userland and onwards).
+
+ [[1]] Change. Date and enumeration elements are trimmed during parsing\
+ There are some feeds that add whitespaces or carriage return characters before or after the proper date or enumeration value. This was causing ROME to fail processing those elements. This is taken care now as all dates elements in all feed types and Modules and the 'channel.skipHours.hour' and 'channel.skipDays.day' (RSS0.91 \- RSS2.0) are trimmed before parsing and setting their values in the beans.
+
+ [[1]] Fix. SyndFeed description now maps to atom:tagline\
+ Previously, atom:info was being mapped to the feed's description. According to the Atom03 spec atom:info should be ignored by parsers, and the more appropriate element is atom:tagline.
+
+ [[1]] Fix. RSS cloud is now generated/parsed correctly\
+ The 'path' attribute from the cloud was not being generated/parsed. The parser now process all cloud attributes and set the cloud to the channel.
+
+ [[1]] Fix. RFC\-822 2 digit years\
+ Previously RFC\-822 dates did not work correctly with 2 digit years. This is now fixed.
+
+ [[1]] Fix. No alternate link causes IndexOutOfBoundsException\
+ Fix bug where no alternate link causes IndexOutOfBoundsException in ConverterForAtom03 (Thanks to Joseph Van Valen).
+
+ [[1]] Change. Date parsing attemps RFC822 on W3C parsing on all feeds\
+ All feed parsers (RSS and Atom) now attemp both RFC822 and W3C parsing on date values.
+
+ [[1]] Fix. XmlFixerReader removes character from stream when parsing an entity that contains an invalid character\
+ Fix bug in XmlFixerReader where an invalid entity such as "&ent\=", gets put back on the stream without the last character (in this example, "&ent\=" becomes "&ent"). This was most visible when the XmlFixerReader encountered an URL with a query string that has more than one parameter (e.g. {{{http://www.url.com/index.html?qp1\=1&qp2\=2}http://www.url.com/index.html?qp1\=1&qp2\=2}}) \-\- all "\=" after the first one would disappear.
+
+ [[1]] Change. DateParser can use additional custom datetime masks\
+ Besides attempting to parse datetime values in W3C and RFC822 formats additional datetime masks can be specified in the /rome.properties files using the 'datetime.extra.masks' property. To indicate multiple masks the '|' character must be used, all other characters are considered part of the mask. As with parser/generators/converter plugins the masks are read from all /rome.properties file in the classpath.
+
+ []
+
+*Changes made from v0.5 to v0.6
+
+
+
+ [[1]] Fix. W3C date\-time parsing now handles date\-time with 'Z' modifier\
+ The W3C date\-time parser was not parsing times using the UTC modifier 'Z'.
+
+ [[1]] Fix. XML prolog encoding parsing was failing when other attributes where present in the prolog\
+ If there was an attribute following the encoding attribute the value of the encoding attribute was misinterpreted. For example, for the XML prolog the detected encoding was <<>> instead of <<>>.
+
+ [[1]] Change. XmlReader lenient behavior gives priority to XML prolog encoding over content\-type charset\
+ In ROME 0.5 the XmlReader first attempts to do a strict charset encoding detection. Only if the strict detection fails it attempts a lenient detection. When the HTTP Content\-Type header is of type <<>> and the header does not specify any charset, RFC 3023 mandates that the charset encoding must be <<>>. It's a common error for sites to use the <<>> MIME type without charset information and indicate the charset encoding in the XML prolog of the document, being the charset encoding in the XML prolog different from <<>>. The XmlReader lenient behavior has been modified to give precedence to the XML prolog charset encoding, if present, over the HTTP Content\-Type charset encoding.
+
+ [[1]] Addition. XML Healer\
+ ROME parsers, SyndFeedInput and WireFeedInput, have a new feature, XML healing.\
+ The XML healing trims the beginning of the XML text document if there are whitespaces, enters or XML comments before the XML prolog or the root element. It also replaces all HTML literal entities occurrences with coded entities. These changes convert feeds technically invalid (from the XML specification perspective) into valid ones allowing the SAX XML parser to successfully parse the XML if there are not other errors in it.\
+ This behavior is active by default. It can be turned on and off using the new 'xmlHealerOn' property in the SyndFeedInput and WireFeedInput classes.\
+ The idea for this feature was taken from the FeedFilter from Jakarta's commons feedparser.
+
+ [[1]] Addition. The XML prolog of generated feeds contains the feed encoding\
+ ROME generators were creating feeds with the XML prolog encoding always set to 'UTF\-8', if the given Writer had another charset encoding things would break for anybody consuming the feed (a mismatch between the char stream charset and what the XML doc says).\
+ The SyndFeedOutput and WireFeedOutput generators now use the SyndFeed and WireFeed 'encoding' property to set the 'encoding' attribute in the XML prolog of the generated feeds. It is the responsibility of the developer to ensure that if the String is written to a character stream the stream charset is the same as the feed encoding property.
+
+ [[1]] Change. SyndFeed to Atom convertion now uses 'escaped' mode for content elements\
+ SyndFeed to Atom converter was using 'xml' mode for content elements. This was breaking feeds with content that was not propertly escaped as it was assumed to be XML fragments.
+
+ [[1]] Change. RSS 2.0 parser and generator now handles DC Module\
+ ROME configuration has been changed so RSS 2.0 parser and generator handle DC Module elements at channel level and item level.
+
+ [[1]] Fix. RSS0.93, RSS0.94 and RSS2.0 'dc:date' element value was being lost under certain conditions\
+ If a feed had 'dc:date' elements but not 'pubDate' elements, the 'dc:date' elements where lost when converting from Channel to SyndFeed.\
+ This was happening for 'dc:date' elements at channel level and at item level.
+
+ [[1]] Fix. RSS 1.0 'rdf:resource' and 'rdf:about' item linking attributes use a unique ID now\
+ The value for the 'rdf:resource' and 'rdf:about' linking attributes was done using the value of the 'link' element. If there is more than one item with the same link the generated feed will be incorrect.\
+ Instead using the link value now the index of the item is used for the linkage between 'rdf:resource' and 'rdf:about' for items.
+
+ [[1]] Fix/Change. Parsing and setting of enumerated elements is case insentive now\
+ Parsing and bean setting of enumerated values (such as RSS skipDay, Atom content mode, etc) are now case insentive, generation is strict (Postel Law).
+
+ [[1]] Fix. Remove enumeration check on 'rel' attribute of Atom link elements\
+ Because a misunderstanding of Atom 0.3 specification the Atom Link bean was checking the value of the 'rel' property against a set of valid values. The check has been removed.
+
+ [[1]] Fix. DC subjects (in RSS versions with native categories) were being lost on conversion to SyndFeed\
+ All RSS versions with native categories (at both channel and item level) now have the following behavior when converting to SyndFeed.\
+ DC subjects are converted to SyndCategories. Native categories are converted to SyndCategories. They are both aggregated in a Set (to remove duplicates) then added to the SyndFeed.\
+ When doing a SyndFeed to Channel conversion, if the RSS version has native categories and handles DC modules the categories will be duplicated as native and DC ones.
+
+ [[1]] Fix/Change. RSS 1.0 rdf:about attribute in the channel.\
+ RSS 1.0 uses the rdf:about attribute at the channel level as an identifier. This was not being parsed or generated (only supported at the item level). Support for this was added along with test cases.
+
+ [[1]] Fix/Change/Addition. Multivalued Dublin Core element support.\
+ Many feeds are using multiple DC elements to tag metadata, the interface for the DCModule has been changed to support Lists of elements, compatibility has been maintained with the existing interface though as the new methods are plural (creators vs. creator), the single value methods will remain as convenience methods. The implementation now uses the lists to represent all of the elements. The parser/generator modules for DC have been updated to reflect these changes along with a few other code cleanups in the DC\* modules.
+
+ [[1]] Fix. Removed length constraint checks from RSS1.0 generator\
+ RSS1.0 specification does not require, only suggests, maximum length for some of the elements. ROME was enforcing those lenghts when generating RSS1.0 feeds. This enforcement has been removed becuase is not mandatory.
+
+ []
+
+*Changes made from v0.4 to v0.5
+
+
+
+ [[1]] Change. Got rid of Enum class\
+ All constants in the beans are Strings now, the corresponding property setters check that the value being set is one of the valid constants. Rome has not business defining an Enum class.
+
+ [[1]] Change. Got rid of ToString interface\
+ This is just an implementation convenience, it was polluting Rome API. Modified ToStringBean to work without requiring an interface and method to propagate the prefix to use with properties.
+
+ [[1]] Change. ObjectBean, ToStringBean, EqualsBean are not part of the public API anymore\
+ These are just an implementation convenience, they were polluting Rome API. Rome bean implementations don't extends ObjectBean anymore. Instead they use it in a delegation pattern. While these classes are not public anymore they are part of Rome implementation.
+
+ [[1]] Change. CopyFrom interface moved to com.sun.syndication.feed package\
+ The common package is gone now that the \*Bean classes are not there anymore. No point keeping a package just for an interface.
+
+ [[1]] Fix. PluginManager was not doing plugin lookup in the defined order\
+ PluginManager (manages parsers, generators and convertors for feeds and modules) was not doing the lookup in order the plugins are defined in the rome.properties files. This is needed for parsers where the lookup involves detecting the feed type and the feed type detection goes needs to go from stronger to weaker.
+
+ [[1]] Addition. Rome now recognizes RSS 2.0 feeds with 'http://backend.userland.com/rss2' namespace\
+ These namespace was defined by an RSS 2.0 draft and later was dropped. There are feeds out there using this namespace and Rome was not parsing them.
+
+ [[1]] Change. By default XmlReader does a lenient charset encoding detection.\
+ If the charset encoding cannot be determined per HTTP MIME and XML specifications the following relaxed detection is performed: If the content type is 'text/html' it replaces it with 'text/xml' and tries the per specifications detection again. Else if the XML prolog had a charset encoding that encoding is used. Else if the content type had a charset encoding that encoding is used. Else 'UTF\-8' is used.\
+ There are 2 new constructors that take a lenient flag to allow strict charset encoding detection. If scrict charset encoding detection is performed and it fails an XmlReaderException is thrown by the constructor. The XmlReaderException contains all the charset encoding information gathered from the stream including the unconsumed stream.
+
+ []
+
+*Changes made from v0.3 to v0.4
+
+
+
+ [[1]] Fix. Date elements on generated feeds use the right format now\
+ There were some Date elements in Atom 0.3, DCModule, SyModule, RSS 0.91 and RSS 0.93 that were incorrectly formating the date \[they were just doing a toString() \]. Now they use the RFC822 and W3C format as indicated in their specs.
+
+ [[1]] Fix. SyndFeed and SyndEntry getModule(DCModule.URI) method always returns a DCModule, never null\
+ This issue is related to Fix #19 in v0.3. The DCModule is 'special' for Synd\*, it must always be there. If it is not, it is created implicitly when needed. This was not happening when asking explicitly for the DCModule through the Synd\* interfaces.
+
+ [[1]] Addition. Added ParseFeedException to the \*Input classes\
+ This new exception report the line and column number in the XML document where the parsing has failed.
+
+ [[1]] Change. Renamed '\*I' interfaces to just '\*' and default implementations to '\*Impl'\
+ The Synd\* and Module interfaces/classes were affected. For example the interface that used to be SyndFeedI is now SyndFeed and the class that used to be SyndFeed is now SyndFeedImpl.
+
+ [[1]] Change. Ant 'build.xml' files have been improved\
+ The build.xml were re\-written instead just using the Maven generated ones.
+
+ [[1]] Fix. DateParser now uses lenient parsing so as to work with JDK 1.5\
+ DateParser currently setLenient to false. This does not work with JDK 1.5. Changing the DateParser to setLient to true.
+
+ [[1]] Change. SyndCategoryListFacade is not a public class anymore\
+ It's now a package private class (it should have been like that in the first place).
+
+ [[1]] Addition. Added a protected constructor to the Synd\*Impl classes\
+ This constructor takes a Class parameter. It allows implementations extending SyndContentImpl to be able to use the ObjectBean functionality with extended interfaces (additional public properties). Use case: Hibernate beans that have an 'Id' Long property, a new interface HSynd\* (extending Synd\*) and a new implementation HSynd\*Impl (extending Synd\*Impl) where the clone(), equals(), hashCode() and toString() methods take the properties of the extension into account.
+
+ [[1]] Project layout change. Moved samples project to subprojects dir\
+ The 'samples' project was moved from 'rome/modules/samples' to 'rome/subprojects/samples'. The 'rome/modules' project is left for Module subprojects only.
+
+ [[1]] Fix. Plugin manager bug didn't allow custom plugins to replace core plugins\
+ All plugins are in a Map keyed off by its type (parsers, generators, converters) or URI (modules). There is also a helper List containing the plugins, this list is scanned when looking for a plugin (for example when selecting the right parser). Plugins were added to the List without checking if another element in the List was using the same key. Now the List is built using the Map values, thus the overwriting works fine.
+
+ [[1]] Fix. RSS 2.0 Converter (Wire \-\> Synd \- Wire) was not processing modules\
+ The RSS 2.0 Converter now processes feed and entry modules both ways.
+
+ [[1]] Fix. New properties introspection mechanism in common classes\
+ The java.beans.Introspector does not work as expected on interface properties (it doesn't scan properties of the super interfaces). Now, a private implementation of a properties introspector is used by the common bean classes.
+
+ [[1]] Change. Refactored private CopyFrom helper class\
+ It was com.sun.syndication.feed.synd.impl.SyndCopyFrom now it is com.sun.syndication.common.impl.CopyFromHelper.
+
+ [[1]] Fix. RSS2.0 Wire\-Synd converter handles propertly RSS and DC categories\
+ If the RSS2.0 feed had DC Module categories (subjects) this would override the RSS native categories. Now they are aggregated.
+
+ [[1]] Change/Fix. CloneableBean can take an ignore\-properties set\
+ This change is useful for bean that have convenience properties mapping to other properties. SyndFeed and SyndEntry that map some of its properties (ie publishedDate, author, categories) to DC Module properties. There is not point cloning the convenience ones as they are just facades.\
+ This fixes a SyndFeedImpl cloning problem with the categories. There is a package private list for the categories to DC subject mapping. The problem was related to accesibility of this package private list implementation by the CloneableBean. The change enables the blacklisting of certain properties (in this categories) when cloning.
+
+ [[1]] Change. Refactored Parsers/Generator classes\
+ Introduced a base parser and base generator to handle modules. For the feed types that define modules support, the modules have to be defined the rome.properties file. For RSS 1.0 and Atom 0.3 Dublin Core and Syndication modules are defined, the first one at feed and entry level the second one at feed level. Note this was already done but hardwired in the specific feed type parsers and generators, now it is done in the base parser and base generator. Some code clean up and removal of duplicated code was also done.
+
+ [[1]] Change. Defined and implemented precedence order for native and module elements in feeds\
+ For feeds supporting modules, some of the module defines elements collide with the feed native elements (this depends on the feed type, and it may affect the data such as publish\-date, author, copyright, categories). The SyndFeed and SyndEntry properties documented as convenience properties are (can be) affected. The convenience properties map into DC Module properties.\
+ Rome now defines precedence of feed native elements over module elements when converting from WireFeed to SyndFeed. This is, in the situation of a clash, the native element data prevails and the the module element data is lost.\
+ When converting from SyndFeed to WireFeed, if a SyndFeed convenience property has a native mapping in the target feed type it will be in both the native element and the DC Module element if the feed type defines support for the DC module. The data will appear twice in the feed, in the native elements and in the DC module elements.
+
+ [[1]] Change. Module namespaces are defined at root element\
+ Module namespaces are always defined in the root element. The ModuleGenerator interface has a new method that returns all the namespaces used by the module, the generators use the namespaces returned by this method to inject them in the feed root element.
+
+ [[1]] Change/Fix. Test cases refactoring\
+ Some refactoring in the test cases for the Synd\* entities. Some minor bugs (typos in constants) were found and fixed in the parsers.\
+ The Ops and Synd tests are 100% complete. Not that they test 100% of Rome functionality but 100% of what they suppose to test.
+
+ [[1]] Fix. Atom 0.3 content elements with XML mode were not being parsed and converted properly\
+ When mode is XML, free text was not being processed, only sub\-elements were being processed.\
+ The Parser when parsing content with XML mode skips Atom namespace in the output of the processed fragment.\
+ The Converter when going down pushes content data using XML mode, which is Atom's default (it was ESCAPED before).
+
+ [[1]] Addition. Constraints in data length and number of items are observed by RSS generators\
+ As part of the generators refactoring the generators now verify the data in the Rome beans does not generate invalid feeds.
+
+ [[1]] Addition. New XmlReader that detects charset encoding\
+ The XmlReader class handles the charset encoding of XML documents in Files, raw streams and HTTP streams. It following the rules defined by HTTP, MIME types and XML specifications. All this is nicely explained by Mark Pilgrim in his blog, {{{http://diveintomark.org/archives/2004/02/13/xml\-media\-types}http://diveintomark.org/archives/2004/02/13/xml\-media\-types}}
+
+ [[1]] Rome now uses JDOM 1.0\
+ Dependencies have been updated to use JDOM 1.0. No code changes were needed because of this.
+
+ [[1]] Change. The length property in the RSS Enclosure bean is now a long\
+ It used to be an int, but as it is meant to specify arbitrary lengths (in could be in the order of several megabytes) it was changed to be a long.
+
+ [[1]] Addition. SyndFeed and SyndEntry beans have a 'uri' property\
+ It is used with RSS0.94 & RSS2.0 guid elements and with Atom0.3 id elements. Refer to {{{./RomeV0.4FeedAndEntryURIMapping.html}Feed and entry URI Mapping}} for a full explanation.
+
+ [[1]] Addition. New sample, FeedServlet\
+ Added a new sample, FeedServlet. This servlet creates a feed and returns a feed.
+
+ [[1]] Change. RSS0.91 Userland and RSS0.91 Netscape are handled as different feed types\
+ Instead having a single set of parser/converter/generator implementations there is one set for each one of them. This allows to differenciate incoming RSS0.91 Userland feeds from RSS0.91 Netscape feeds as well as choosing which one to generate.
+
+ []
+
+*Changes made from v0.2 to v0.3
+
+
+
+ [[1]] Changed loading mechanism for parsers, generators and converters\
+ Previous mechanism was complicated and it wouldn't work in server environments where you cannot alter System properties at will.\
+ Now there are no properties to set. Just including a rome.properties file in the root of a JAR file will make Rome to load any parser, generator or converter defined in the properties file and included in the JAR file (To be documented).
+
+ [[1]] Added Modules support to RSS 2.0 parser and generator\
+ We were only looking for modules in RSS 1.0 and Atom 0.3. Now we also look in RSS 2.0.
+
+ [[1]] Modules parsers and generators are now per feed type\
+ They were global, now each feed type parser and generator has it's own set of modules parsers and generators. They are configurable in the rome.properties file.
+
+ [[1]] All parsers, generators and converters are loaded once per definition\
+ There were some cases we were loading them on every WireFeedParser/WireFeedGenerator instantiation. As they are all thread\-safe we just use one instance.
+
+ [[1]] Changed some implementation (hidden) class names\
+ Some typos corrections and adding consistency to the naming.
+
+ [[1]] Added Fetcher module\
+ Added a HTTP fetcher with conditional get and gzip support (See modules/fetcher)
+
+ [[1]] Modified the samples module build to fix error\
+ Previouly some people were having a maven error trying to run some of the samples. This should now be fixed
+
+ [[1]] Removed methods with byte stream signatures from Rome IO classes\
+ They have no way to know what the encoding is or has to be and they are using the platform default. That does not always work, for example when doing HTTP where the default is ISO\-8859\-1.\
+ Leaving the char streams one and let the developer to do the right thing (Rome cannot do any magic here).
+
+ [[1]] Added getModule(String uri) to SyndFeedI, Atom Feed and RSS Channel\
+ There was not way to obtain a specific module using the module URI, you had to obtain the module list and iterate looking for the module. The getModule(string uri) is a convenience method in all the feed beans to do that.
+
+ [[1]] New. Added 'encoding' property to WireFeed and SyndFeedI/SyndFeed\
+ Impact: It affects RSS, Atom and SyndFeed syndication beans.\
+ It's not being set or use by parsers and generators as they always deal with a char strean where the charset is already set.\
+ The converters, going from Channel/Feed 2 SyndFeed and vice versa are wired to pass the encoding if set.
+
+ [[1]] Fix. CloneableBean array cloning bug\
+ Impact: It affects all Rome beans as they all extend ObjectBean that uses CloneableBean\
+ Arrays were not being cloned but copy by reference. This was affecting all Rome beans as they all extend ObjectBean.
+
+ [[1]] Change. CloneableBean, Basic (primitives & string) types not cloned anymore\
+ Impact: It affects all Rome beans as they all extend ObjectBean that uses CloneableBean\
+ Basic types are inmutable, no need to clone them. As things are done using reflection there were unnecessary objects creation.
+
+ [[1]] Change. CloneableBean, added Date to list of Basic types\
+ Impact: It affects all Rome beans as they all extend ObjectBean that uses CloneableBean\
+ Same reasoning as #12
+
+ [[1]] Change/Fix. EqualsBeans, works on defined class\
+ Impact: It affects all Rome beans as they all extend ObjectBean, which uses EqualsBean\
+ EqualsBean checks for equality by comparing all properties. Until now it was doing this using all properties of the class implementing the bean. This behavior is not correct as implementations may have other properties than the defined in the public interface (and example is: a SyndFeedI implementation for Hibernate that has to have an ID field, and this would apply to all bean interfaces).\
+ Because of this change, both EqualsBean and ObjectBean take a Class parameter in the constructor. Equals will limit the comparison for equality to the properties of that class. If there is not interface for the bean, just the bean implementation (this is the case of Channel and Feed), the implementation Class is passed
+
+ [[1]] Change/Fix. ToStringBean, works on defined class\
+ Same as #14 but on ToStringBean instead EqualsBean
+
+ [[1]] New. Added copyFrom functionality to synd.\* and module.\* beans\
+ Impact: It affect all synd.\* and module.\* beans and other classes that extend ObjectBean.\
+ A new interface 'CopyFrom' has been added to commons.\
+ synd.\* and module.\* bean interfaces implement this interface and their implementations implement the copyFrom functionality.\
+ The copyFrom functionality allows copying a complete bean feed from one implementation to another. The obvious use case is from the default bean implementation to a persistent aware (ie Hibernate) implementation.\
+ The implementation uses the same pattern used by EqualsBean, ConeableBean, it's in the synd.impl.\* package, the supporting class is call SyndCopyFrom.\
+ Note that SyndCategories does not support the copyFrom functionality as it's just a convenience way of accessing DCModule's subjects (where DCModule supports copyFrom). The short explanation is that categories still work and are there after a copyFrom.
+
+ [[1]] Fix. WireFeed constructor was passing the WireFeed.class to ObjectBean\
+ rss.Channel, atom.Feed & WeatherChannel constructor implementations only, no change to their signatures.\
+ The class is used for property scanning for toString, equals behavior of the ObjectBean.
+
+ [[1]] Fix. copyFrom was failing with Enum properties\
+ It was not possible to do a copyFrom on a feed with SyModule data as it had Enum properties.\
+ Wrong comparison of classes when checking basic types, in the case of enumeration classes has to check it extends Enum not equality.
+
+ [[1]] Fix. SyndFeed and SyndEntry where losing Modules\
+ If they had modules other than DCModule they were being dropped when accessing convenience methods (getCategories, getLanguage, etc).\
+ The Synd\* convenience methods just map to the DCModule properties. If there is no DCModule a new one is created if needed. When this happened instead bean added to the list of current modules a new list with just the DCModule was being set.
+
+ [[1]] New Sample and tutorial for creating a feed\
+ A new sample and tutorial that creates and writes a feed has been added.
+
+ [[1]] New Sample showing how to add a Module bean, parser and generator to Rome\
+ This sample defines a dummy module for use with RSS 1.0 (it can work also with RSS 2.0 and Atom 0.3). Still have to write tutorial
+
+ [[1]] Undoing change #13 as Date is not inmutable\
+ The Date class is not inmutable, CloneableBean now clones Date properties.
+
+ []
+
+*Changes made from v0.1 to v0.2
+
+
+
+ [[1]] FeedInput, added default constructor. Semantics is 'validation off'\
+ We forgot to added it when it was added to SyndFeed.\
+ NOTE that validation is not implemented yet. We need DTDs/XML\-Schemas for the different feed syndication types.
+
+ [[1]] FeedOutput and SyndOutput outputW3CDom() method typo correction\
+ Fixed typo in outputW3CDom() method, it was ouptutW3CDom().
+
+ [[1]] AbstractFeed, renamed to WireFeed\
+ Never liked Abstract in the name. From Java inheritance it makes sense, but from the syndication feed perspective doesn't. It's the super class of the 2 wire feed beans Rome has, RSS Channel and Atom Feed.
+
+ [[1]] Renamed SyndFeed createRealFeed(feedType) method to createWireFeed(feedType)\
+ For consistency with change #3
+
+ [[1]] SyndFeed, added feedType property\
+ Read/write property. It indicates what was the feed type of the WireFeed the SyndFeed was created from. And the feed type a WireFeed created with createWireFeed() will have.
+
+ [[1]] WireFeed, renamed type property to feedType\
+ For consistency with #5. Also it's more clear what the type is about.
+
+ [[1]] Overloaded SyndFeed createRealFeed() with a no parameter signature
+
+ [[1]] FeedOutput, removed feed type from constructor\
+ It now uses the WireFeed feedType property.
+
+ [[1]] SyndOutput, removed feed type from constructor\
+ It now uses the SyndFeed feedType property define in #5.
+
+ [[1]] FeedOutput, removed getType() method\
+ Now FeedOutput uses the WireFeed feedType property.
+
+ [[1]] Removed dependency on Jakarta Commons Codec library\
+ We were using the Codec component to do Base64 encoding/decoding. Based on feedback to reduce component depencies we've removed this one (yes, we implemented a Base64 encoder/decoder).
+
+ [[1]] Removed dependency on Xerces library\
+ This was an unnecessary dependency as Rome requeries JDK 1.4\+ which includes JAXP implementation. JDOM can use that one.
+
+ [[1]] Renamed syndication.io classes/interfaces\
+ Renaming for naming consistency and to reflect on what type of feed they work on.
+
++------+
+
+FeedInput --> WireFeedInput
+FeedOutput --> WireFeedOutput
+FeedParser --> WireFeedParser
+FeedGenerator --> WireFeedGenerator
+SyndInput --> SyndFeedInput
+SyndOutput --> SyndFeedOutputt
+
++------+
+
+
+ [[1]] Removed syndication.util package, PlugableClasses is now private\
+ The PlugableClasses class has no business in Rome public API, it's implementation specific, it has been hidden (it should be replaced later with a micro\-container).
+
+ [[1]] Added samples to the Rome project directory structure\
+ Rome samples are a sub\-project located at rome/modules/sample.
+
+ []
diff --git a/src/site/apt/HowRomeWorks/RomeV0.4TutorialDefiningACustomModuleBeanParserAndGenerator.apt b/src/site/apt/HowRomeWorks/RomeV0.4TutorialDefiningACustomModuleBeanParserAndGenerator.apt
new file mode 100644
index 0000000..bd6f2fb
--- /dev/null
+++ b/src/site/apt/HowRomeWorks/RomeV0.4TutorialDefiningACustomModuleBeanParserAndGenerator.apt
@@ -0,0 +1,363 @@
+ -----
+ Rome v0.4 Tutorial, Defining a Custom Module (bean, parser and generator)
+ -----
+ mkurz
+ -----
+ 2011-08-14 17:34:02.657
+ -----
+
+Rome v0.4 Tutorial, Defining a Custom Module (bean, parser and generator)
+
+
+ <> Synd J2SE 1.4\+, JDOM 1.0 and Rome 0.4.
+
+
+ This tutorial walks through the steps of creating a custom module for syndication feeds that support additional namespaces (such as RSS 1.0, RSS 2.0 and Atom 0.3).
+
+
+ To understand this tutorial you should be familiar the with Rome API and with the use of modules in syndication feeds.
+
+
+ Out of the box Rome parsers and generators support plug\-ability of modules for RSS 1.0, RSS 2.0 and Atom 0.3 at both feed and item/entry levels. Also support for the Dublin Core and Syndication modules is provided.
+
+
+ The complete source for this tutorial is in the Rome samples bundle as well as in SVN.
+
+
+*What is the intended outcome of the tutorial?
+
+
+ The goal is to add support for a hypothetical Sample Module by defining a module bean, module parser and module generator and the necessary configuration to wire the parser and generator to an RSS 1.0 parser and RSS 1.0 generator.
+
+
+ The sample module defines 3 elements, 'bar', 'foo' and 'date', where 'bar' and 'date' may occur at most once and the 'foo' element may occur several times. For example, a feed with the Sample Module data would look like:
+
+
+
++------+
+
+
+
+
+ RSS 1.0 Feed with Sample Module
+ http://rome.dev.java.net
+ This is a feed showing how to use a custom module with Rome
+
+
+
+
+
+
+ Channel bar
+ Channel first foo
+ Channel second foo
+
+
+ Title of Item 01
+ http://rome.dev.java.net/item01
+ Item 01 does not have Sample module data
+
+
+ Title of Item 02
+ http://rome.dev.java.net/item02
+ Item 02 has Sample module data
+ Item 02 bar
+ Item 02 only foo
+ 2004-07-27T00:00+00:00
+
+
+
++------+
+
+*Sample Module Bean
+
+
+ First we must start with the bean interface, SampleModule. SampleModule must extend Module. The Module interface defines the getUri() method, which will return a URI identifying the module. The Module interface also extends the Cloneable, ToString and CopyFrom interfaces to ensure that the beans provide support for basic features as cloning, equality, toString, etc. (for more details on this check the {{{http://wiki.java.net/twiki/bin/view/Javawsxml/Rome04Common}Understanding the Rome common classes and interfaces}} document).
+
+
+ The SampleModule's URI is defined as a constant, accessible via the getURI() instance method. This is for convenience and good practice only.
+
+
+ Then the module defines 3 properties: bar (String), foos (List) and date (Date). The elements of the foos property list must be strings (wishing for Java 5 generics already?).
+
+
+
++------+
+
+public interface SampleModule extends Module,CopyFrom {
+
+ public static final String URI = "http://rome.dev.java.net/module/sample/1.0";
+
+ public String getBar();
+ public void setBar(String bar);
+
+ public List getFoos();
+ public void setFoos(List foos);
+
+ public Date getDate();
+ public void setDate(Date date);
+}
+
++------+
+
+ Next we have to write the bean implementation, SampleModuleImpl.
+
+
+ SampleModuleImpl extends ModuleImpl. ModuleImpl is the default implementation of the \=\=Module interface. ModuleImpl extends ObjectBean which provides equals, hashCode, toString and clone support for the properties of the class given in the constructor (SampleModule). Also the URI of the Sample module is indicated; it will be used by the Module.getUri() method.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ ...
+ public SampleModule() {
+ super(SampleModule.class,SampleModule.URI);
+ }
+
+ public String getBar() {
+ return _bar;
+ }
+ ...
+
++------+
+
+ The module properties are just Java Bean properties. The only catch is to follow Rome semantics for Collection properties: in the case of a null value for the collection, an empty collection must be returned.. Also, following Rome semantics, all properties are by reference, including mutable ones.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ private String _bar;
+ private List _foos;
+ private Date _date;
+ ...
+ public void setBar(String bar) {
+ _bar = bar;
+ }
+
+ public List getFoos() {
+ return (_foos==null) ? (_foos=new ArrayList()) : _foos;
+ }
+
+ public void setFoos(List foos) {
+ _foos = foos;
+ }
+
+ public Date getDate() {
+ return _date;
+ }
+
+ public void setDate(Date date) {
+ _date = date;
+ }
+
++------+
+
+ Now the weird part: the bits for the CopyFrom logic. The {{{http://wiki.java.net/twiki/bin/view/Javawsxml/Rome04Common}Understanding the Rome common classes and interfaces}} document fully explains the CopyFrom logic in detail. In short, the CopyFrom interface is to support copying properties from one implementation of a bean (defined through an interface) to another implementation of the same bean.
+
+
+ The getInterface() method returns the bean interface of the implementation (this is necessary for collections containing sub\-classes such as a list of modules).
+
+
+ The copyFrom() method copies all the properties from the parameter object (which must be a SampleModule implementation) into the caller bean properties. Note that the copyFrom must do a deep copy.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ ...
+ public Class getInterface() {
+ return SampleModuleI.class;
+ }
+
+ public void copyFrom(Object obj) {
+ SampleModule sm = (SampleModule) obj;
+ setBar(sm.getBar());
+ List foos = new ArrayList(sm.getFoos()); // this is enough for the copy because the list elements are inmutable (Strings)
+ setFoos(foos);
+ setDate((Date)sm.getDate().clone()); // because Date is not inmutable.
+ }
+
+}
+
++------+
+
+*Sample Module Parser
+
+
+ The sample module parser must implement the ModuleParser interface. This interface defines 2 methods, getNamespaceUri() that returns the URI of the module and parse(Element) which extracts the module elements from the given Element.
+
+
+ The feed parsers will invoke the module parser with a feed element or with an item element. The module parser must look for module elements in the children of the given element. That is was the Sample parser is doing when looking for 'bar', 'foo' and 'date' children elements in the received element.
+
+
+ In the case of the 'foo' element it looks for all occurrences as the Sample module schema allows for more than one occurrence of the 'foo' element. A SampleModule bean is created and the found values are set into it. For the 'date' element it assumes its a date value in W3C datetime format.
+
+
+ If no Sample Module elements are found in the feed, the parse(Element) method returns null. This is to avoid having an empty instance of a module \-not present in the feed\- in the feed bean or in the item bean.
+
+
+
++------+
+
+public class SampleModuleParser implements ModuleParser {
+
+ private static final Namespace SAMPLE_NS = Namespace.getNamespace("sample", SampleModule.URI);
+
+ public String getNamespaceUri() {
+ return SampleModule.URI;
+ }
+
+ public Module parse(Element dcRoot) {
+ boolean foundSomething = false;
+ SampleModule fm = new SampleModuleImpl();
+
+ Element e = dcRoot.getChild("bar", SAMPLE_NS);
+ if (e != null) {
+ foundSomething = true;
+ fm.setBar(e.getText());
+ }
+ List eList = dcRoot.getChildren("foo", SAMPLE_NS);
+ if (eList.size() > 0) {
+ foundSomething = true;
+ fm.setFoos(parseFoos(eList));
+ }
+ e = dcRoot.getChild("date", SAMPLE_NS);
+ if (e != null) {
+ foundSomething = true;
+ fm.setDate(DateParser.parseW3CDateTime(e.getText()));
+ }
+ return (foundSomething) ? fm : null;
+ }
+
+ private List parseFoos(List eList) {
+ List foos = new ArrayList();
+ for (int i = 0; i < eList.size(); i++) {
+ Element e = (Element) eList.get(i);
+ foos.add(e.getText());
+ }
+ return foos;
+ }
+
+}
+
++------+
+
+*Sample Module Generator
+
+
+ The sample module generator must implement the ModuleGenerator interface. This interface defines 2 methods, getNamespaceUri() that returns the URI of the module and generate(ModuleI,Element) which injects the module data into the given Element.
+
+
+ The feed generator will invoke the module generator with a feed element or with an item element. The module generator must inject the module properties into the given element (which is a feed or an item). This injection has to be done using the right namespace. The set of namespaces returned by the getNamespaces() method will be used to declare the namespaces used by the module in the feed root element.
+
+
+ If no Sample Module bean is in the feed bean the module generator is not invoked at all.
+
+
+
++------+
+
+public class SampleModuleGenerator implements ModuleGenerator {
+ private static final Namespace SAMPLE_NS = Namespace.getNamespace("sample", SampleModule.URI);
+
+ public String getNamespaceUri() {
+ return SampleModule.URI;
+ }
+
+ private static final Set NAMESPACES;
+
+ static {
+ Set nss = new HashSet();
+ nss.add(SAMPLE_NS);
+ NAMESPACES = Collections.unmodifiableSet(nss);
+ }
+
+ public Set getNamespaceUris() {
+ return NAMESPACES;
+ }
+
+ public void generate(Module module, Element element) {
+
+ // this is not necessary, it is done to avoid the namespace definition in every item.
+ Element root = element;
+ while (root.getParent()!=null && root.getParent() instanceof Element) {
+ root = (Element) element.getParent();
+ }
+ root.addNamespaceDeclaration(SAMPLE_NS);
+
+ SampleModuleI fm = (SampleModule)module;
+ if (fm.getBar() != null) {
+ element.addContent(generateSimpleElement("bar", fm.getBar()));
+ }
+ List foos = fm.getFoos();
+ for (int i = 0; i < foos.size(); i++) {
+ element.addContent(generateSimpleElement("foo",foos.get(i).toString()));
+ }
+ if (fm.getDate() != null) {
+ element.addContent(generateSimpleElement("date", DateParser.formatW3CDateTime(fm.getDate())));
+ }
+ }
+
+ protected Element generateSimpleElement(String name, String value) {
+ Element element = new Element(name, SAMPLE_NS);
+ element.addContent(value);
+ return element;
+ }
+
+}
+
++------+
+
+*Configuration to make Rome process Sample Module in feeds
+
+
+ The last step is to setup the configuration file to indicate to Rome how and when to use the Sample Module parser and generator.
+
+
+ The configuration is stored in a Properties file, 'rome.properties', that has to be in the root of the classpath or JAR where the Sample Module bean, parser and generator classes are.
+
+
+ You must indicate the syndication feed formats (ie RSS 1.0) that must be aware of the Sample Module. You must indicate if the Sample Module is available for feed or item elements, or for both. You must indicate both the parser and the generator classes.
+
+
+ Following is the 'rome.properties' file for the Sample Module, it's defined for RSS 1.0 only, for both feed and item elements.
+
+
+
++------+
+
+# Parsers for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleParser.classes=com.sun.syndication.samples.module.SampleModuleParser
+
+# Parsers for RSS 1.0 item modules
+#
+rss_1.0.item.ModuleParser.classes=com.sun.syndication.samples.module.SampleModuleParser
+
+# Generators for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleGenerator.classes=com.sun.syndication.samples.module.SampleModuleGenerator
+
+# Generators for RSS_1.0 entry modules
+#
+rss_1.0.item.ModuleGenerator.classes=com.sun.syndication.samples.module.SampleModuleGenerator
+
++------+
+
+ If you are defining more than one module, indicate the parser and generator implementation classes separated by commas or spaces.
+
+
+*Using the Sample Module from the SyndFeed beans
+
+
+ They will be there, just use them. You may get the SampleModule bean using the getModule(String Uri) method of the SyndFeed bean and the SyndEntry bean.
+
+
+ Adding or replacing a syndication feed parser, generator or converter goes along the same lines of what it has been explained in the tutorial for modules. This is explained in the {{{http://wiki.java.net/twiki/bin/view/Javawsxml/Rome04Plugins}Rome Plugins Mechanism}} topic.
+
diff --git a/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToAggregateManySyndicationFeedsIntoASingleOne.apt b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToAggregateManySyndicationFeedsIntoASingleOne.apt
new file mode 100644
index 0000000..0edf895
--- /dev/null
+++ b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToAggregateManySyndicationFeedsIntoASingleOne.apt
@@ -0,0 +1,146 @@
+ -----
+ Rome v0.4 Tutorial, Using Rome to aggregate many syndication feeds into a single one
+ -----
+ mkurz
+ -----
+ 2011-08-14 14:57:11.190
+ -----
+
+Rome v0.4 Tutorial, Using Rome to aggregate many syndication feeds into a single one
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and Rome 0.4.
+
+
+ Rome represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with Rome are all lightweight classes.
+
+
+ Rome includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using Rome are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the InputStream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ Rome also includes generators to create syndication feeds out of SyndFeed instances. The SyndFeedOutput class does this generation. The SyndFeedOutput will generate a syndication feed of the feed type indicated by the SyndFeed object being output. The following two lines of code show how to create a syndication feed output from a SyndFeed instance:
+
+
+
++------+
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,new PrintWriter(System.out));
+
++------+
+
+ The first line creates a SyndFeedOutput instance that will produce syndication feeds. It can output feeds of any type (rss_0.9, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0 & atom_0.3), the SyndFeed feedType property indicates the type. The second line writes the SyndFeed as a syndication feed into the application's output.
+
+
+ SyndFeed instances can also be created and populated within the code. For example:
+
+
+
++------+
+
+SyndFeed aggrFeed = new SyndFeedImpl();
+aggrFeed.setFeedType("rss_1.0");
+aggrFeed.setTitle("Aggregated Feed");
+aggrFeed.setDescription("Anonymous Aggregated Feed");
+aggrFeed.setAuthor("anonymous");
+aggrFeed.setLink("http://www.anonymous.com");
+
++------+
+
+ The snipped of code above creates a SyndFeed instance using the default implementation provided by Rome, sets the feed type to RSS 1.0, sets the title, description, author and link properties of the feed.
+
+
+ SyndFeed properties can be modified, assigned to other SyndFeed instances, removed, etc. It's important to remember that the getters/setters semantics defined for all SyndFeed properties (and properties of its properties) is a copy by reference, not by value. In other words if you alter the property of a SyndFeed property you are altering the SyndFeed. Or, another example, if you assign the list of entries of one SyndFeed instance to another SyndFeed isntance and then you modify the list or any of the entries in the list, you are modifying the entries of both SyndFeed instances.
+
+
+ The following lines of code show how to copy the entries of a SyndFeed instance being read (inFeed) into a SyndFeed instance being created within the application (feed):
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.ArrayList;
+
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.SyndFeedImpl;
+import com.sun.syndication.io.SyndFeedOutput;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It aggregates a list of RSS/Atom feeds (they can be of different types)
+ * into a single feed of the specified type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedAggregator {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length>=2) {
+ try {
+ String outputType = args[0];
+
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(outputType);
+
+ feed.setTitle("Aggregated Feed");
+ feed.setDescription("Anonymous Aggregated Feed");
+ feed.setAuthor("anonymous");
+ feed.setLink("http://www.anonymous.com");
+
+ List entries = new ArrayList();
+ feed.setEntries(entries);
+
+ for (int i=1;i> Synd J2SE 1.4\+, JDOM 1.0 and Rome 0.4.
+
+
+ Rome represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with Rome are all lightweight classes.
+
+
+ Rome includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using Rome are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the InputStream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ Rome also includes generators to create syndication feeds out of SyndFeed instances. The SyndFeedOutput class does this generation. The SyndFeedOutput will generate a syndication feed of the feed type indicated by the SyndFeed object being output. The following two lines of code show how to create a syndication feed output from a SyndFeed instance:
+
+
+
++------+
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,new PrintWriter(System.out));
+
++------+
+
+ The first line creates a SyndFeedOutput instance that will produce syndication feeds. It can output feeds of any type (rss_0.9, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0 & atom_0.3), the SyndFeed feedType property indicates the type. The second line writes the SyndFeed as a syndication feed into the application's output.
+
+
+ Following is the full code for a Java application that reads a syndication feed and converts it to other syndication feed type, writing the converted feed to the application's output.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.SyndFeedOutput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It Converts any RSS/Atom feed type to a an RSS/Atom feed of the
+ * specified type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedConverter {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==2) {
+ try {
+ String outputType = args[0];
+
+ URL feedUrl = new URL(args[1]);
+
+ SyndFeedInput input = new SyndFeedInput();
+ SyndFeed feed = input.build(new XmlReader(feedUrl));
+ feed.setFeedType(outputType);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,new PrintWriter(System.out));
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedConverter converts between syndication feeds types.");
+ System.out.println("The first parameter must be the feed type to convert to.");
+ System.out.println(" [valid values are: rss_0.9, rss_0.91, rss_0.92, rss_0.93, ]");
+ System.out.println(" [ rss_0.94, rss_1.0, rss_2.0 & atom_0.3 ]");
+ System.out.println("The second parameter must be the URL of the feed to convert.");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToCreateAndWriteASyndicationFeed.apt b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToCreateAndWriteASyndicationFeed.apt
new file mode 100644
index 0000000..abe4af9
--- /dev/null
+++ b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToCreateAndWriteASyndicationFeed.apt
@@ -0,0 +1,204 @@
+ -----
+ Rome v0.4 Tutorial, Using Rome to create and write a syndication feed
+ -----
+ mkurz
+ -----
+ 2011-08-14 14:59:35.761
+ -----
+
+Rome v0.4 Tutorial, Using Rome to create and write a syndication feed
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and Rome 0.4.
+
+
+ Rome represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.feed.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with Rome are all lightweight classes.
+
+
+ Creating a feed with SyndFeed beans consists of creating beans and setting their properties. The following code fragments show how a SyndFeed bean with 3 entries is created.
+
+
+ First the SyndFeed instance is created, the preferred syndication format is set and the feed header info (title, link, description) is also set.
+
+
+
++------+
+
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(feedType);
+
+ feed.setTitle("Sample Feed (created with Rome)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using Rome (Java syndication utilities");
+
++------+
+
+ Then a list for entries is created, entries are created and added to the list. Each entry is set with a title, link, published date and a description. The description for the first entry is plain test, for the third entry is HTML. After each entry is created is added to the list.
+
+
+
++------+
+
+ List entries = new ArrayList();
+ SyndEntry entry;
+ SyndContent description;
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v1.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Initial release of Rome");
+ entry.setDescription(description);
+ entries.add(entry);
+ ...
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v3.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-07-27"));
+ description = new SyndContentImpl();
+ description.setType("text/html");
+ description.setValue("
More Bug fixes, mor API changes, some new features and some Unit testing
");
+ entry.setDescription(description);
+ entries.add(entry);
+
++------+
+
+ Finally the list with entries is added to the SyndFeed bean.
+
+
+
++------+
+
+ feed.setEntries(entries);
+
++------+
+
+ The SyndFeed bean is now ready to be written out to a syndication feed XML document. Note that any of supported syndication formats can be set in the feedType property.
+
+
+ Rome includes generators that allow producing syndication feed XML documents from SyndFeed instances. The SyndFeedOutput class handles the generation of the syndication feed XML documents on any of the supported feed formats (RSS and Atom). The developer does not need to worry about selecting the right generator for a syndication feed, the SyndFeedOutput will take care of it by looking at the information in the SyndFeed bean. All it takes to write a syndication feed XML document using Rome \-assuming you have a SyndFeed bean and a Writer instance\- are the following lines of code:
+
+
+
++------+
+
+ SyndFeed feed = ...;
+ Writer writer = ...;
+
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,writer);
+
++------+
+
+ First a SyndFeedOutput instance is created, this instance will work with any syndication feed type (RSS and Atom versions). Then the feed and the writer are given to the SyndFeedOutput instance, the SyndFeedOutput will write the syndication feed XML document represented by the SyndFeed bean to the Writer stream.
+
+
+ Following is the full code for a Java application that creates a syndication feed and writes it to a file in the specified syndication format.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import java.io.FileWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * It creates a feed and writes it to a file.
+ *
+ *
+ */
+public class FeedWriter {
+
+ private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==2) {
+ try {
+ String feedType = args[0];
+ String fileName = args[1];
+
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(feedType);
+
+ feed.setTitle("Sample Feed (created with Rome)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using Rome (Java syndication utilities");
+
+ List entries = new ArrayList();
+ SyndEntry entry;
+ SyndContent description;
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v1.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Initial release of Rome");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v2.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Bug fixes, minor API changes and some new features");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v3.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-07-27"));
+ description = new SyndContentImpl();
+ description.setType("text/html");
+ description.setValue("
More Bug fixes, mor API changes, some new features and some Unit testing
");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ feed.setEntries(entries);
+
+ Writer writer = new FileWriter(fileName);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,writer);
+ writer.close();
+
+ System.out.println("The feed has been written to the file ["+fileName+"]");
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedWriter creates a RSS/Atom feed and writes it to a file.");
+ System.out.println("The first parameter must be the syndication format for the feed");
+ System.out.println(" (rss_0.90, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0 rss_2.0 or atom_0.3)");
+ System.out.println("The second parameter must be the file name for the feed");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToReadASyndicationFeed.apt b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToReadASyndicationFeed.apt
new file mode 100644
index 0000000..f14ae76
--- /dev/null
+++ b/src/site/apt/HowRomeWorks/RomeV0.4TutorialUsingRomeToReadASyndicationFeed.apt
@@ -0,0 +1,93 @@
+ -----
+ Rome v0.4 Tutorial, Using Rome to read a syndication feed
+ -----
+ mkurz
+ -----
+ 2011-08-14 14:48:33.636
+ -----
+
+Rome v0.4 Tutorial, Using Rome to read a syndication feed
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and Rome 0.4.
+
+
+ Rome represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with Rome are all lightweight classes.
+
+
+ Rome includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using Rome are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the char based input stream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ The default SyndFeed implementation has a detailed and clear toString() implementation. The following line just prints it to the application's output.
+
+
+
++------+
+
+System.out.println(feed);
+
++------+
+
+ Following is the full code for a Java application that reads a syndication feed and prints the SyndFeed bean to the application's output.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It Reads and prints any RSS/Atom feed type.
+ *
");
+entry.setDescription(description);
+entries.add(entry);
+
++------+
+
+ Finally the list with entries is added to the SyndFeedI bean.
+
+
+
++------+
+
+feed.setEntries(entries);
+
++------+
+
+ The SyndFeedI bean is now ready to be written out to a syndication feed XML document. Note that any of supported syndication formats can be set in the feedType property.
+
+
+ Rome includes generators that allow producing syndication feed XML documents from SyndFeedI instances. The SyndFeedOutput class handles the generation of the syndication feed XML documents on any of the supported feed formats (RSS and Atom). The developer does not need to worry about selecting the right generator for a syndication feed, the SyndFeedOutput will take care of it by looking at the information in the SyndFeedI bean. All it takes to write a syndication feed XML document using Rome \-assuming you have a SyndFeedI bean and a Writer instance\- are the following lines of code:
+
+
+
++------+
+
+SyndFeedI feed = ...;
+Writer writer = ...;
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,writer);
+
++------+
+
+ First a SyndFeedOutput instance is created, this instance will work with any syndication feed type (RSS and Atom versions). Then the feed and the writer are given to the SyndFeedOutput instance, the SyndFeedOutput will write the syndication feed XML document represented by the SyndFeedI bean to the Writer stream.
+
+
+ Following is the full code for a Java application that creates a syndication feed and writes it to a file in the specified syndication format.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import java.io.FileWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * It creates a feed and writes it to a file.
+ *
+ *
+ */
+public class FeedWriter {
+
+ private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==2) {
+ try {
+ String feedType = args[0];
+ String fileName = args[1];
+
+ SyndFeedI feed = new SyndFeed();
+ feed.setFeedType(feedType);
+
+ feed.setTitle("Sample Feed (created with Rome)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using Rome (Java syndication utilities");
+
+ List entries = new ArrayList();
+ SyndEntryI entry;
+ SyndContentI description;
+
+ entry = new SyndEntry();
+ entry.setTitle("Rome v1.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ description = new SyndContent();
+ description.setType("text/plain");
+ description.setValue("Initial release of Rome");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntry();
+ entry.setTitle("Rome v2.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
+ description = new SyndContent();
+ description.setType("text/plain");
+ description.setValue("Bug fixes, minor API changes and some new features");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntry();
+ entry.setTitle("Rome v3.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-07-27"));
+ description = new SyndContent();
+ description.setType("text/html");
+ description.setValue("
More Bug fixes, mor API changes, some new features and some Unit testing
");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ feed.setEntries(entries);
+
+ Writer writer = new FileWriter(fileName);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,writer);
+ writer.close();
+
+ System.out.println("The feed has been written to the file ["+fileName+"]");
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedWriter creates a RSS/Atom feed and writes it to a file.");
+ System.out.println("The first parameter must be the syndication format for the feed");
+ System.out.println(" (rss_0.90, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0 rss_2.0 or atom_0.3)");
+ System.out.println("The second parameter must be the file name for the feed");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/RomeV0.3TutorialUsingRomeToReadASyndicationFeed.apt b/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/RomeV0.3TutorialUsingRomeToReadASyndicationFeed.apt
new file mode 100644
index 0000000..137740d
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/RomeV0.3TutorialUsingRomeToReadASyndicationFeed.apt
@@ -0,0 +1,95 @@
+ -----
+ Rome v0.3 Tutorial, Using Rome to read a syndication feed
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:53:37.700
+ -----
+
+Rome v0.3 Tutorial, Using Rome to read a syndication feed
+
+
+ <> J2SE 1.4\+, JDOM B10 and Rome 0.3.
+
+
+ Rome represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeedI interface. The SyndFeedI interfaces and its properties follow the Java Bean patterns. The default implementations provided with Rome are all lightweight classes.
+
+
+ Rome includes parsers to process syndication feeds into SyndFeedI instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using Rome are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeedI feed = input.build(new InputStreamReader(feedUrl.openStream()));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the char based input stream of a URL pointing to the feed. The SyndFeedInput.build() method returns a SyndFeedI instance that can be easily processed.
+
+
+ Obtaining the char based input stream has been simplified in this tutorial, the sample code in the distribution is a little more complex to handle charset encodings properly.
+
+
+ The default SyndFeedI implementation has a detailed and clear toString() implementation. The following line just prints it to the application's output.
+
+
+
++------+
+
+System.out.println(feed);
+
++------+
+
+ Following is the full code for a Java application that reads a syndication feed and prints the SyndFeedI bean to the application's output.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import com.sun.syndication.feed.synd.SyndFeedI;
+import com.sun.syndication.io.SyndFeedInput;
+
+/**
+ * It Reads and prints any RSS/Atom feed type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedReader {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==1) {
+ try {
+ URL feedUrl = new URL(args[0]);
+
+ SyndFeedInput input = new SyndFeedInput();
+ SyndFeedI feed = input.build(new InputStreamReader(feedUrl.openStream()));
+
+ System.out.println(feed);
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
+ System.out.println("The first parameter must be the URL of the feed to read.");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/index.apt b/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/index.apt
new file mode 100644
index 0000000..a26cdab
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.3Beta/RomeV0.3Tutorials/index.apt
@@ -0,0 +1,29 @@
+ -----
+ Rome v0.3 Tutorials
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:49:23.826
+ -----
+
+Rome v0.3 Tutorials
+
+
+ The following tutorials show how to use the Rome API. They focus on the higher abstraction layer of classes offered by Rome, what we call the Synd\* classes. By using the Synd\* classes developers don't have to deal with the specifics of any syndication feed. They work with normalized feeds, the Synd\* feeds. This makes it much easier to write applications that have to deal with all the variety of syndication feed types in use today.
+
+
+
+ [[1]] {{{./RomeV0.3TutorialUsingRomeToReadASyndicationFeed.html}Using Rome to read a syndication feed}}
+
+ [[1]] {{{./RomeV0.3TutorialUsingRomeToConvertASyndicationFeedFromOneTypeToAnother.html}Using Rome to convert a syndication feed from one type to another}}
+
+ [[1]] {{{./RomeV0.3TutorialUsingRomeToAggregateManySyndicationFeedsIntoASingleOne.html}Using Rome to aggregate many syndication feeds into a single one}}
+
+ [[1]] {{{./RomeV0.3TutorialUsingRomeToCreateAndWriteASyndicationFeed.html}Using Rome to create and write a feed}} <<<(New)>>>
+
+ [[1]] {{{./RomeV0.3TutorialDefiningACustomModuleBeanParserAndGenerator.html}Defining a Custom Module bean, parser and generator}} <<<(New)>>>
+
+ []
+
+ For instructions on how to build and run the samples used in the tutorials {{{./RomeV0.3HowToBuildAndRunTheTutorialsSampleCode.html}click here}}.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.3Beta/index.apt b/src/site/apt/ROMEReleases/ROME0.3Beta/index.apt
new file mode 100644
index 0000000..600a35f
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.3Beta/index.apt
@@ -0,0 +1,60 @@
+ -----
+ ROME 0.3 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:47:07.902
+ -----
+
+ROME 0.3 Beta
+
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM Beta 10}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.3\-src.zip}rome\-0.3\-src.zip}}
+
+ * {{{./rome\-0.3.tar.gz}rome\-0.3.tar.gz}}
+
+ * {{{./rome\-0.3.zip}rome\-0.3.zip}}
+
+ * {{{./rome\-0.3\-src.tar.gz}rome\-0.3\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.3\-src.tar.gz}rome\-samples\-0.3\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.3\-src.zip}rome\-samples\-0.3\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{./RomeV0.3Tutorials/index.html}Tutorials}} (2 New ones)
+
+ * Changes Log
+
+ []
+
+*Known Issues
+
+
+
+ * Same issues as Rome v0.1
+
+ * When processing XML documents with DTD (ie: Netscape RSS 0.91) if the XML parser implementation is not Xerces and the system does not have access ot the internet, the XML parser will fail.
+
+ * If the feed starts with a {{{http://www.unicode.org/faq/utf_bom.html#BOM}BOM}} the JAXP SAX parser may fail, using {{{http://xml.apache.org/xerces2\-j}Xerces 2.6.2}} addresses the problem.
+
+ []
diff --git a/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4HowToBuildAndRunTheTutorialsSampleCode.apt b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4HowToBuildAndRunTheTutorialsSampleCode.apt
new file mode 100644
index 0000000..e570db0
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4HowToBuildAndRunTheTutorialsSampleCode.apt
@@ -0,0 +1,84 @@
+ -----
+ Rome v0.4, How to build and run the tutorials sample code
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:32:24.939
+ -----
+
+Rome v0.4, How to build and run the tutorials sample code
+
+
+*Building the samples with Maven
+
+
+ This is, as usual, the easiest way.
+
+
+ There's only one configuration step: Maven downloads dependencies from an online repository (by default ibiblio), to a local repository (on UNIX usually in \~/.maven/repository). Because the rome distribution is not yet on ibiblio, you need to add it yourself, either to your local repository, or to your own intranet maven repository if you have such a thing in your organization.
+
+
+ If you built Rome run maven jar:install in the rome project to install Rome's jar in your Maven repository.
+
+
+ If you got Rome binary distribution copy the Rome's jar file to your Maven repository (on UNIX that would be <<>>).
+
+
+ Then building the samples it's easy as a pie, just run maven jar in the samples sub\-project and you are all set.
+
+
+ To build the sample Web Application, just run maven war in the samples sub\-project. The WAR file, <<>>, will be created under the <<>> directory.
+
+
+*Building the samples with Ant
+
+
+ The targets present in the build.xml are very helpful, ant get\-deps will download from ibiblio to rome\-samples/target/lib all the jar files Rome depends on and are needed for building an application using Rome.
+
+
+ In order to build the samples (or any subprojects), you'll need to first ensure that rome itself is built. You can do this simply by running ant in the project root directory.
+
+
+ Once this is done, change to the samples directory, and just run ant. This will produce two files, rome\-samples.jar which contains the sample applications, and rome\-samples.war which will contain a deployable web application war file for the FeedServlet sample.
+
+
+*Running the samples with Maven
+
+
+ The Maven goals for running the samples are defined in maven.xml. They should all generate the same file named toto, but somehow it ends up empty. However the output is correctly sent to the console. We'll fix that glitch later.
+
+
+
+ * <<>> runs the FeedAggregator sample
+
+ * <<>> runs the FeedConverter sample
+
+ * <<>> runs the FeedReader sample
+
+ * <<>> runs the FeedWriter sample
+
+ * <<>> runs the FeedConverter sample against a file with Sample Module data (shows off custom module plugin)
+
+ []
+
+ To run the sample Web Application you'll need to deploy the WAR file into your servlet container. If you are using Tomcat 4 or Tomcat 5 and the WAR file was dropped in the <<<$\{TOMCAT\}/webapps>>> directory the URL for the <<>> would be {{{http://localhost:8080/rome\-samples/feed}http://localhost:8080/rome\-samples/feed}} in a default localhost Tomcat installation.
+
+
+*Running the samples with Ant
+
+
+ All ant targets for the samples generate the same file named toto: feel free to customize this build.xml to your own needs. Also today all these targets depends on the jar target, which represents some overhead if you have already built. Get rid of that once your project is well setup.
+
+
+
+ * <<>> runs the FeedAggregator sample
+
+ * <<>> runs the FeedConverter sample
+
+ * <<>> runs the FeedReader sample
+
+ * <<>> runs the FeedWriter sample
+
+ * <<>> runs the FeedConverter sample against a file with Sample Module data (shows off custom module plugin)
+
+ []
diff --git a/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4TutorialUsingRomeWithinAServletToCreateAndReturnAFeed.apt b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4TutorialUsingRomeWithinAServletToCreateAndReturnAFeed.apt
new file mode 100644
index 0000000..ffe3122
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4TutorialUsingRomeWithinAServletToCreateAndReturnAFeed.apt
@@ -0,0 +1,242 @@
+ -----
+ Rome v0.4 Tutorial, Using Rome within a Servlet to create and return a feed
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:29:48.938
+ -----
+
+Rome v0.4 Tutorial, Using Rome within a Servlet to create and return a feed
+
+
+ <> J2SE 1.4\+, Servlet Container 2.3\+, JDOM 1.0 and Rome 0.4.
+
+
+ This sample consists of a servlet that serves a feed as response. The feed type (RSS in any of its variants or Atom) can be specified as a URL parameter when requesting the feed. The returned feed is hardwired in the sample and it would be straight forward to modify the sample to generate the feed dynamically (i.e. from data stored in a database).
+
+
+ The core logic of the <<>> is in the following fragment of code:
+
+
+
++------+
+
+public class FeedServlet extends HttpServlet {
+ ...
+
+ public void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
+ ...
+ SyndFeed feed = getFeed(req);
+
+ String feedType = req.getParameter(FEED_TYPE);
+ feedType = (feedType!=null) ? feedType : _defaultFeedType;
+ feed.setFeedType(feedType);
+
+ res.setContentType(MIME_TYPE);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,res.getWriter());
+ ...
+ }
+
+ protected SyndFeed getFeed(HttpServletRequest req) throws IOException,FeedException {
+ SyndFeed feed = new SyndFeedImpl();
+ feed = ...
+ return feed;
+ }
+
+}
+
++------+
+
+ The servlet returns a feed upon HTTP GET requests with the <<>> method.
+
+
+ First the <<>> bean is obtained by invoking the <<>> method, the request object is passed as it could be used to obtain request contextual information to create the feed. How to create a feed using SyndFeed bean is explained in detail in the {{{../../../HowRomeWorks/RomeV0.4TutorialUsingRomeToCreateAndWriteASyndicationFeed.html}Using Rome to create and write a feed}} Tutorial.
+
+
+ Then the feed type of the response is determined, first looking at the request parameters and falling back to a default feed type (specified by a servlet init parameter) if the type is not indicated in the request parameters. Setting the feed type in the feed bean will indicate the <<>> the feed type to output.
+
+
+ Finally, the response is set with the proper content type (the MIME_TYPE constant is 'application/xml; charset\=UTF\-8') and the feed is written to response writer using the <<>> output classes.
+
+
+ Following is the full code for the servlet.
+
+
+
++------+
+
+package com.sun.syndication.samples.servlet;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Sample Servlet that serves a feed created with Rome.
+ *
+ * The feed type is determined by the 'type' request parameter, if the parameter is missing it defaults
+ * to the 'default.feed.type' servlet init parameter, if the init parameter is missing it defaults to 'atom_0.3'
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedServlet extends HttpServlet {
+ private static final String DEFAULT_FEED_TYPE = "default.feed.type";
+ private static final String FEED_TYPE = "type";
+ private static final String MIME_TYPE = "application/xml; charset=UTF-8";
+ private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed";
+
+ private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
+
+ private String _defaultFeedType;
+
+ public void init() {
+ _defaultFeedType = getServletConfig().getInitParameter(DEFAULT_FEED_TYPE);
+ _defaultFeedType = (_defaultFeedType!=null) ? _defaultFeedType : "atom_0.3";
+ }
+
+ public void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
+ try {
+ SyndFeed feed = getFeed(req);
+
+ String feedType = req.getParameter(FEED_TYPE);
+ feedType = (feedType!=null) ? feedType : _defaultFeedType;
+ feed.setFeedType(feedType);
+
+ res.setContentType(MIME_TYPE);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,res.getWriter());
+ }
+ catch (FeedException ex) {
+ String msg = COULD_NOT_GENERATE_FEED_ERROR;
+ log(msg,ex);
+ res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg);
+ }
+ }
+
+ protected SyndFeed getFeed(HttpServletRequest req) throws IOException,FeedException {
+ SyndFeed feed = new SyndFeedImpl();
+
+ feed.setTitle("Sample Feed (created with Rome)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using Rome (Java syndication utilities");
+
+ List entries = new ArrayList();
+ SyndEntry entry;
+ SyndContent description;
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v0.1");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+ try {
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ }
+ catch (ParseException ex) {
+ // IT CANNOT HAPPEN WITH THIS SAMPLE
+ }
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Initial release of Rome");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v0.2");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
+ try {
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
+ }
+ catch (ParseException ex) {
+ // IT CANNOT HAPPEN WITH THIS SAMPLE
+ }
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Bug fixes, minor API changes and some new features"+
+ "
");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ feed.setEntries(entries);
+
+ return feed;
+ }
+
+}
+
++------+
+
+ To use the <<>> we need to create a Web Application. For the Web Application we need a deployment descriptor, the <<>> file:
+
+
+
++------+
+
+
+
+
+
+ Rome Samples
+
+
+ FeedServlet
+ com.sun.syndication.samples.servlet.FeedServlet
+
+ default.feed.type
+ rss_2.0
+
+
+
+
+ FeedServlet
+ /feed
+
+
+
+
++------+
+
+ To build the sample Web Application, just run maven war in the samples sub\-project. The WAR file, <<>>, will be created under the <<>> directory. Deploy the WAR in a servlet container and the <<>> should be up an running. If you are using Tomcat 4 or Tomcat 5 and the WAR file was dropped in the <<<$\{TOMCAT\}/webapps>>> directory the URL for the <<>> would be {{{http://localhost:8080/rome\-samples/feed}http://localhost:8080/rome\-samples/feed}} in a default localhost Tomcat installation.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/index.apt b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/index.apt
new file mode 100644
index 0000000..c9d2343
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/index.apt
@@ -0,0 +1,31 @@
+ -----
+ Rome v0.4 Tutorials
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:26:41.706
+ -----
+
+Rome v0.4 Tutorials
+
+
+ The following tutorials show how to use the Rome API. They focus on the higher abstraction layer of classes offered by Rome, what we call the Synd\* classes. By using the Synd\* classes developers don't have to deal with the specifics of any syndication feed. They work with normalized feeds, the Synd\* feeds. This makes it much easier to write applications that have to deal with all the variety of syndication feed types in use today.
+
+
+
+ [[1]] {{{../../../HowRomeWorks/RomeV0.4TutorialUsingRomeToReadASyndicationFeed.html}Using Rome to read a syndication feed}}
+
+ [[1]] {{{../../../HowRomeWorks/RomeV0.4TutorialUsingRomeToConvertASyndicationFeedFromOneTypeToAnother.html}Using Rome to convert a syndication feed from one type to another}}
+
+ [[1]] {{{../../../HowRomeWorks/RomeV0.4TutorialUsingRomeToAggregateManySyndicationFeedsIntoASingleOne.html}Using Rome to aggregate many syndication feeds into a single one}}
+
+ [[1]] {{{../../../HowRomeWorks/RomeV0.4TutorialUsingRomeToCreateAndWriteASyndicationFeed.html}Using Rome to create and write a feed}}
+
+ [[1]] {{{../../../HowRomeWorks/RomeV0.4TutorialDefiningACustomModuleBeanParserAndGenerator.html}Defining a Custom Module bean, parser and generator}}
+
+ [[1]] {{{./RomeV0.4TutorialUsingRomeWithinAServletToCreateAndReturnAFeed.html}Using Rome within a Servlet to create and return a feed}} <<<(NEW)>>>
+
+ []
+
+ For instructions on how to build and run the samples used in the tutorials {{{./RomeV0.4HowToBuildAndRunTheTutorialsSampleCode.html}click here}}.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.4Beta/index.apt b/src/site/apt/ROMEReleases/ROME0.4Beta/index.apt
new file mode 100644
index 0000000..eb4f70f
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.4Beta/index.apt
@@ -0,0 +1,94 @@
+ -----
+ ROME 0.4 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 13:35:59.126
+ -----
+
+ROME 0.4 Beta
+
+
+*What is New, Highlights
+
+
+
+ * Changed naming convention of bean interfaces and implementations (i.e.: SyndFeedI/SyndFeed are now SyndFeed/SyndFeedImpl)
+
+ * New XmlReader that handles charset encoding as defined by the XML 1.0 specification and RFC 3023
+
+ * Support of RSS 0.91 Netscape and RSS 0.91 Userland as distinct feed types
+
+ * All feed types have Modules support
+
+ * Added checks to generators reducing the chances of generating invalid feeds
+
+ * Comprehensive Unit testing
+
+ * Bug fixes
+
+ * More documentation and samples
+
+ * Dependencies, upgraded to JDom 1.0 and removed Xerces
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.4\-src.zip}rome\-0.4\-src.zip}}
+
+ * {{{./rome\-0.4.tar.gz}rome\-0.4.tar.gz}}
+
+ * {{{./rome\-0.4.zip}rome\-0.4.zip}}
+
+ * {{{./rome\-0.4\-src.tar.gz}rome\-0.4\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.4\-src.tar.gz}rome\-samples\-0.4\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.4\-src.zip}rome\-samples\-0.4\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{./RomeV0.4Tutorials/index.html}Tutorials}}
+
+ * {{{../../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../../HowRomeWorks/index.html}How ROME Works}}, Understanding Rome (a detailed overview by Dave Johnson)
+
+ * {{{../../HowRomeWorks/UnderstandingTheRomeCommonClassesAndInterfaces.html}Rome common Package}}, bean utilities, enums, copying and clonning
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how Rome helps getting the right charset encoding
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.5Beta/ROMET-Shirt.apt b/src/site/apt/ROMEReleases/ROME0.5Beta/ROMET-Shirt.apt
new file mode 100644
index 0000000..e353641
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.5Beta/ROMET-Shirt.apt
@@ -0,0 +1,26 @@
+ -----
+ ROME T-Shirt
+ -----
+ mkurz
+ -----
+ 2011-08-15 12:34:25.248
+ -----
+
+ROME T\-Shirt
+
+
+ I made it quickly before taking a plane, and ruined my iron when trying to press it myself on a T\-shirt, but it's better than nothing and a T\-shirt is vital to an open source project!
+
+
+ It's at {{{http://www.cafepress.com/chanezon.13794826}http://www.cafepress.com/chanezon.13794826}}
+
+
+ Else just print the design yourself and iron it on a T\-shirt (advice from P@ the practical guy: don't try to iron glossy paper photo on a T\-shirt
+
+
+
+[http://blogs.sun.com/roller/resources/pat/_rome-t-shirt.png]
+
+
+ \-\- {{{http://wiki.java.net/twiki/bin/view/Main/PatrickChanezon}PatrickChanezon}} \- 10 Jan 2005
+
diff --git a/src/site/apt/ROMEReleases/ROME0.5Beta/index.apt b/src/site/apt/ROMEReleases/ROME0.5Beta/index.apt
new file mode 100644
index 0000000..859be00
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.5Beta/index.apt
@@ -0,0 +1,94 @@
+ -----
+ ROME 0.5 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 12:32:36.814
+ -----
+
+ROME 0.5 Beta
+
+
+*What is New, Highlights
+
+
+
+ * Removed common package and classes from the public API
+
+ * Removed Enum class, using constants now
+
+ * XmlReader now has a lenient behavior for charset encoding detection
+
+ * Bug fixes
+
+ * {{{./ROMET\-Shirt.html}ROME T\-Shirt (rome)}}
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.5\-src.zip}rome\-0.5\-src.zip}}
+
+ * {{{./rome\-0.5.tar.gz}rome\-0.5.tar.gz}}
+
+ * {{{./rome\-0.5.zip}rome\-0.5.zip}}
+
+ * {{{./rome\-0.5\-src.tar.gz}rome\-0.5\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.5\-src.tar.gz}rome\-samples\-0.5\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.5\-src.zip}rome\-samples\-0.5\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/index.html}Tutorials}}
+
+ * {{{../../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../../HowRomeWorks/index.html}How ROME Works}}, Understanding ROME, a detailed overview by Dave Johnson (This doc is based on ROME v0.4)
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how ROME helps getting the right charset encoding
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}Creating a custom Module}}, creating all necessary pieces, bean, parser and generator
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/TheCopyFromInterface.html}The CopyFrom interface}}
+
+
+
+ * Implementation documents
+
+ * {{{../../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/UnderstandingRssAndAtOMUtilitiEsROMEBeanUtilities.html}ROME bean utilities, equals, toString and clonning}}
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.6Beta.apt b/src/site/apt/ROMEReleases/ROME0.6Beta.apt
new file mode 100644
index 0000000..911eeaa
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.6Beta.apt
@@ -0,0 +1,89 @@
+ -----
+ ROME 0.6 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 12:36:05.599
+ -----
+
+ROME 0.6 Beta
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 0.6 is reusing ROME 0.5 Wiki pages as most of the changes are internal and the documentation has not changed.
+
+
+*What is New, Highlights
+
+
+
+ * Bug fixes
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.6\-src.zip}rome\-0.6\-src.zip}}
+
+ * {{{./rome\-0.6.tar.gz}rome\-0.6.tar.gz}}
+
+ * {{{./rome\-0.6.zip}rome\-0.6.zip}}
+
+ * {{{./rome\-0.6\-src.tar.gz}rome\-0.6\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.6\-src.tar.gz}rome\-samples\-0.6\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.6\-src.zip}rome\-samples\-0.6\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/index.html}Tutorials}}
+
+ * {{{../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../HowRomeWorks/index.html}How ROME Works}}, Understanding ROME, a detailed overview by Dave Johnson (This doc is based on ROME v0.4)
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how ROME helps getting the right charset encoding
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}Creating a custom Module}}, creating all necessary pieces, bean, parser and generator
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/TheCopyFromInterface.html}The CopyFrom interface}}
+
+
+
+ * Implementation documents
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/UnderstandingRssAndAtOMUtilitiEsROMEBeanUtilities.html}ROME bean utilities, equals, toString and clonning}}
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.7Beta.apt b/src/site/apt/ROMEReleases/ROME0.7Beta.apt
new file mode 100644
index 0000000..1d3e43b
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.7Beta.apt
@@ -0,0 +1,91 @@
+ -----
+ ROME 0.7 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 12:08:20.698
+ -----
+
+ROME 0.7 Beta
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 0.7 is reusing ROME 0.5 Wiki pages as most of the changes are internal.
+
+
+*What is New, Highlights
+
+
+
+ * We got a cool logo
+
+ * Bug fixes
+
+ * Several Date and time parsing improvements including support for custom parsing masks
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.7\-src.zip}rome\-0.7\-src.zip}}
+
+ * {{{./rome\-0.7.tar.gz}rome\-0.7.tar.gz}}
+
+ * {{{./rome\-0.7.zip}rome\-0.7.zip}}
+
+ * {{{./rome\-0.7\-src.tar.gz}rome\-0.7\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.7\-src.tar.gz}rome\-samples\-0.7\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.7\-src.zip}rome\-samples\-0.7\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/index.html}Tutorials}}
+
+ * {{{../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../HowRomeWorks/index.html}How ROME Works}}, Understanding ROME, a detailed overview by Dave Johnson (This doc is based on ROME v0.4)
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how ROME helps getting the right charset encoding
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}Creating a custom Module}}, creating all necessary pieces, bean, parser and generator
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/TheCopyFromInterface.html}The CopyFrom interface}}
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/UnderstandingRssAndAtOMUtilitiEsROMEBeanUtilities.html}ROME bean utilities, equals, toString and clonning}}
+
+ * {{{../RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.html}Customizing Date and time parsing}} in the rome.properties file <>
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
diff --git a/src/site/apt/ROMEReleases/ROME0.8Beta.apt b/src/site/apt/ROMEReleases/ROME0.8Beta.apt
new file mode 100644
index 0000000..4b9f28b
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.8Beta.apt
@@ -0,0 +1,94 @@
+ -----
+ ROME 0.8 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 12:35:29.441
+ -----
+
+ROME 0.8 Beta
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 0.8 is reusing ROME 0.7 Wiki pages as much as possible.
+
+
+*What is New, Highlights
+
+
+
+ * ROME now supports the final version of the Atom Syndication Format {{{http://www.ietf.org/rfc/rfc4287}RFC 4287}}: let's Nuke all these feeds! <>
+
+ * Enclosure support at the Synd level, for all our podcaster friends
+
+ * Bug fixes
+
+ * details in the ChangeList
+
+ * Modules galore: Content, iTunes Podcast, Slash, Google Base, Creative Commons, MediaRSS
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-0.8\-src.zip}rome\-0.8\-src.zip}}
+
+ * {{{./rome\-0.8.tar.gz}rome\-0.8.tar.gz}}
+
+ * {{{./rome\-0.8.zip}rome\-0.8.zip}}
+
+ * {{{./rome\-0.8\-src.tar.gz}rome\-0.8\-src.tar.gz}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/index.html}Tutorials}}
+
+ * {{{../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../HowRomeWorks/index.html}How ROME Works}}, Understanding ROME, a detailed overview by Dave Johnson (This doc is based on ROME v0.4)
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how ROME helps getting the right charset encoding
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}Creating a custom Module}}, creating all necessary pieces, bean, parser and generator
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/TheCopyFromInterface.html}The CopyFrom interface}}
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/UnderstandingRssAndAtOMUtilitiEsROMEBeanUtilities.html}ROME bean utilities, equals, toString and clonning}}
+
+ * {{{../RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.html}Customizing Date and time parsing}} in the rome.properties file <>
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
+
+ \-\- {{{http://wiki.java.net/twiki/bin/view/Main/PatrickChanezon}PatrickChanezon}} \- 02 Feb 2006
+
diff --git a/src/site/apt/ROMEReleases/ROME0.9Beta.apt b/src/site/apt/ROMEReleases/ROME0.9Beta.apt
new file mode 100644
index 0000000..60c93d9
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME0.9Beta.apt
@@ -0,0 +1,100 @@
+ -----
+ ROME 0.9 Beta
+ -----
+ mkurz
+ -----
+ 2011-08-15 11:58:02.820
+ -----
+
+ROME 0.9 Beta
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 0.9 is reusing ROME 0.8 Wiki pages as much as possible.
+
+
+*What is New, Highlights
+
+
+
+ * Better support for RSS feeds that use
+
+ * Better mapping for RSS description/content and Atom summary/content
+
+ * Numerous bug fixes
+
+ * Details in the ChangeList
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-samples\-0.9.tar.gz}rome\-samples\-0.9.tar.gz}}
+
+ * {{{./rome\-0.9.tar.gz}rome\-0.9.tar.gz}}
+
+ * {{{./rome\-0.9\-src.zip}rome\-0.9\-src.zip}}
+
+ * {{{./rome\-0.9\-src.tar.gz}rome\-0.9\-src.tar.gz}}
+
+ * {{{./rome\-0.9.zip}rome\-0.9.zip}}
+
+ * {{{./rome\-samples\-0.9.zip}rome\-samples\-0.9.zip}}
+
+ * {{{./rome\-samples\-0.9\-src.tar.gz}rome\-samples\-0.9\-src.tar.gz}}
+
+ * {{{./rome\-samples\-0.9\-src.zip}rome\-samples\-0.9\-src.zip}}
+
+ []
+
+*Additional Information
+
+
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/index.html}Tutorials}}
+
+ * {{{../ChangeLog.html}Changes Log}}
+
+ * Inside ROME, How Things Work
+
+ * {{{../HowRomeWorks/index.html}How ROME Works}}, Understanding ROME, a detailed overview by Dave Johnson (This doc is based on ROME v0.4)
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}}, bootstrap, adding and changing parsers, generators, converters and modules
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.html}Feeds Date Elements}}, how Date data is mapped to SyndFeed and SyndEntry
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.html}Feed and Entry URI Mapping}}, how SyndFeed and SyndEntry 'uri' properties map to concrete feed elements
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/XMLCharsetEncodingDetectionHowRssAndAtOMUtilitiEsROMEHelpsGettingTheRightCharsetEncoding.html}XML Charset Encoding Detection}}, how ROME helps getting the right charset encoding
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}Creating a custom Module}}, creating all necessary pieces, bean, parser and generator
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/TheCopyFromInterface.html}The CopyFrom interface}}
+
+ * {{{../RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/UnderstandingRssAndAtOMUtilitiEsROMEBeanUtilities.html}ROME bean utilities, equals, toString and clonning}}
+
+ * {{{../RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.html}Customizing Date and time parsing}} in the rome.properties file <>
+
+
+
+ []
+
+*Known Issues
+
+
+ None.
+
+
+ \-\- Main.snoopdave \- 06 Dec 2006
+
diff --git a/src/site/apt/ROMEReleases/ROME1.0RC1.apt b/src/site/apt/ROMEReleases/ROME1.0RC1.apt
new file mode 100644
index 0000000..8247234
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME1.0RC1.apt
@@ -0,0 +1,68 @@
+ -----
+ ROME 1.0 RC1
+ -----
+ mkurz
+ -----
+ 2011-08-14 17:22:56.542
+ -----
+
+ROME 1.0 RC1
+
+
+*Rss and atOM utiliEs (ROME) v1.0 RC1 (16 Jul 2008)
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 1.0 is reusing wikis from previous versions as there are not significant changes.
+
+
+*What is New, Highlights
+
+
+
+ * Several XmlReader fixes
+
+ * Several Atom 1.0 bean, parser and generator fixes
+
+ * Some RSS fixes
+
+ * Removal of unused namespaces
+
+ * Details in the {{{../ChangeLog.html}change log}}
+
+ []
+
+*Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-samples\-1.0RC1\-src.zip}rome\-samples\-1.0RC1\-src.zip}}
+
+ * {{{./rome\-1.0RC1\-src.zip}rome\-1.0RC1\-src.zip}}
+
+ * {{{./rome\-1.0RC1.tar.gz}rome\-1.0RC1.tar.gz}}
+
+ * {{{./rome\-1.0RC1.zip}rome\-1.0RC1.zip}}
+
+ * {{{./rome\-1.0RC1\-src.tar.gz}rome\-1.0RC1\-src.tar.gz}}
+
+ * {{{./rome\-samples\-1.0RC1\-src.tar.gz}rome\-samples\-1.0RC1\-src.tar.gz}}
+
+ []
+
+*Documentation
+
+
+
+ * {{{http://rome.dev.java.net/apidocs/1_0RC1/overview\-summary.html}Javadocs}}
+
+ []
diff --git a/src/site/apt/ROMEReleases/ROME1.0RC2.apt b/src/site/apt/ROMEReleases/ROME1.0RC2.apt
new file mode 100644
index 0000000..1f16383
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME1.0RC2.apt
@@ -0,0 +1,58 @@
+ -----
+ ROME 1.0 RC2
+ -----
+ mkurz
+ -----
+ 2011-08-14 17:19:36.245
+ -----
+
+ROME 1.0 RC2
+
+
+*What is New, Highlights
+
+
+
+ * ROME is now {{{../HowToBuildRome.html}built using Maven 2}}
+
+ * ROME jars are now available in the {{{../ROMEAndMaven2.html}java.net Maven repository}}
+
+ * More lenient handling of Number formats during parsing
+
+ * Better date parsing for Atom dates
+
+ * Complete details in the {{{../ChangeLog.html}change log}}
+
+ []
+
+*Dependencies
+
+
+
+ * {{{http://wiki.java.net/twiki/bin/view/Javawsxml/J2SE}J2SE}} 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}
+
+ []
+
+*Downloads
+
+
+
+ * {{{./rome\-fetcher\-1.0RC2\-src.zip}rome\-fetcher\-1.0RC2\-src.zip}}
+
+ * {{{./rome\-1.0RC2.jar}rome\-1.0RC2.jar}}
+
+ * {{{./rome\-1.0RC2\-javadoc.jar}rome\-1.0RC2\-javadoc.jar}}
+
+ * {{{./rome\-1.0RC2\-sources.jar}rome\-1.0RC2\-sources.jar}}
+
+ []
+
+*Documentation
+
+
+
+ * {{{http://rome.dev.java.net/apidocs/1_0RC2/overview\-summary.html}Javadocs}}
+
+ []
diff --git a/src/site/apt/ROMEReleases/ROME1.0Release.apt b/src/site/apt/ROMEReleases/ROME1.0Release.apt
new file mode 100644
index 0000000..5bdbebe
--- /dev/null
+++ b/src/site/apt/ROMEReleases/ROME1.0Release.apt
@@ -0,0 +1,66 @@
+ -----
+ ROME 1.0 Release
+ -----
+ mkurz
+ -----
+ 2011-08-15 14:48:27.959
+ -----
+
+ROME 1.0 Release
+
+
+
+
+
+*What is New / Highlights
+
+
+ Normally each release of ROME includes a whole new set of Wiki pages with the corresponding version number. ROME 1.0 is reusing wikis from previous versions as there are not significant changes.
+
+
+
+ * ROME can now optionally preserve WireFeed (ie, Atom/RSS specific) data and make it available via the SyndFeed data model. See {{{../PreservingWireFeeds.html}PreservingWireFeeds}} for further details
+
+ []
+
+
+ * Complete details in the {{{../ChangeLog.html}change log}}
+
+ []
+
+**Downloads
+
+
+
+ * {{{./rome\-1.0.jar}rome\-1.0.jar}}
+
+ * {{{./rome\-1.0\-sources.jar}rome\-1.0\-sources.jar}}
+
+ * {{{./rome\-1.0\-javadoc.jar}rome\-1.0\-javadoc.jar}}
+
+ * {{{./rome\-1.0.jar}rome\-1.0.jar}}
+
+ * {{{./rome\-1.0\-javadoc.jar}rome\-1.0\-javadoc.jar}}
+
+ * {{{./rome\-1.0\-sources.jar}rome\-1.0\-sources.jar}}
+
+ []
+
+**Dependencies
+
+
+
+ * J2SE 1.4\+
+
+ * {{{http://www.jdom.org/}JDOM 1.0}}\
+
+
+ []
+
+**Documentation
+
+
+
+ * {{{http://rome.dev.java.net/apidocs/1_0/overview\-summary.html}Javadocs}}
+
+ []
diff --git a/src/site/apt/ROMEReleases/index.apt b/src/site/apt/ROMEReleases/index.apt
new file mode 100644
index 0000000..b9b95fc
--- /dev/null
+++ b/src/site/apt/ROMEReleases/index.apt
@@ -0,0 +1,38 @@
+ -----
+ ROME Releases
+ -----
+ mkurz
+ -----
+ 2011-08-15 14:51:42.765
+ -----
+
+ROME Releases
+
+
+*----+--+
+||Version||Release Date|
+*----+--+
+|{{{./ROME1.0Release.html}ROME 1.0}}|March 12, 2009|
+*----+--+
+|{{{./ROME1.0RC2.html}Rome v1.0 RC2}}|Jan 9, 2009|
+*----+--+
+|{{{./ROME1.0RC1.html}Rome v1.0 RC1}}|Jul 16, 2007|
+*----+--+
+|{{{./ROME0.9Beta.html}Rome v0.9 Beta}}|Dec 11, 2006|
+*----+--+
+|{{{./ROME0.8Beta.html}Rome v0.8 Beta}}|Feb 01, 2006|
+*----+--+
+|{{{./ROME0.7Beta.html}Rome v0.7 Beta}}|Sep 09, 2005|
+*----+--+
+|{{{./ROME0.6Beta.html}Rome v0.6 Beta}}|Apr 01, 2005|
+*----+--+
+|{{{./ROME0.5Beta/index.html}Rome v0.5 Beta}}|Jan 10, 2005|
+*----+--+
+|{{{./ROME0.4Beta/index.html}Rome v0.4 Beta}}|Sep 27, 2004|
+*----+--+
+|{{{./ROME0.3Beta/index.html}Rome v0.3 Beta}}|Jul 28, 2004|
+*----+--+
+|{{{./ROME0.2Beta/index.html}Rome v0.2 Beta}}|Jun 16, 2004|
+*----+--+
+|{{{./ROME0.1Beta/index.html}Rome v0.1 Beta}}|Jun 08, 2004|
+*----+--+
diff --git a/src/site/apt/RomeAPIFAQ.apt b/src/site/apt/RomeAPIFAQ.apt
new file mode 100644
index 0000000..c3a3985
--- /dev/null
+++ b/src/site/apt/RomeAPIFAQ.apt
@@ -0,0 +1,127 @@
+ -----
+ Rome API FAQ
+ -----
+ mkurz
+ -----
+ 2011-08-14 14:37:43.201
+ -----
+
+Rome API FAQ
+
+
+ As we were designing and implementing Rome we had discusssions, brainstorming and code reviews on the API. We've captured them in this document.
+
+
+*Do SyndFeed support arbitrary Metadata?
+
+
+ Yes, using what we call Modules. Currently we support the 2 modules defined in RSS 1.0, {{{http://purl.org/rss/1.0/modules/dc/}Dublin Core}} and {{{http://purl.org/rss/1.0/modules/syndication/}Syndication}}. They are wired when converting from SyndFeed beans to RSS/Atom feeds beans and vice versa. We use the RSS 1.0 terminology of Modules because RSS 1.0 is the specification that defined and used extensibility the most. RSS 2.0 and Atom use XML namespaces to extend the feed.
+
+
+ However we will develop, and encourage developers to develop Rome specific Modules to handle future RSS 2.0 and Atom extensions.
+
+
+ If additional modules are defined to express metadata the converters should be modified to handle them. And the same goes for the parsers and generators or RSS/Atom feeds.
+
+
+*Why those package, interfaces, classes and method names?
+
+
+ We've struggled (and still are struggling) with names. We renamed and moved things around until we got dizzy. If you have suggestions please let us know.
+
+
+*Where are the parser, generator and converter implementations?
+
+
+ They are in hidden (not javadoc\-ed) packages within the Rome jar file. Their classes are loaded using declarations in a properties file. It is possible for developers to add or replace implementations of these components without modifying Rome source code, just by indicating an addition properties file to look for extra implementation classes.
+
+
+*What are the interfaces and classes in the syndication.common package for? And why most bean (or interface) extend/implement them?
+
+
+ At first we got tired of modifying the toString() methods every time we were adding/removing a property. As we were strictly following the Bean patterns we wrote a toString() method that would traverse the properties and print them. Then we went recursively. Then we refactor that into an interface and provided an adapter.
+
+
+ Later we did the same to handle equals/hashcode, which is very useful when using Maps.
+
+
+ To complete the task we did the same for cloning, providing deep cloning support.
+
+
+ The ObjectBean is a base class that implements all these features. All Rome beans extend ObjectBean getting a toString, equals, hashcode and clone support for free.
+
+
+*What are the property values when not set?
+
+
+ For Boolean is <>. For numbers is 1. For String is null. For collections is an empty collection (even if you set it to null you get an empty collection). For all other objects is null.
+
+
+*Are properties copied by value or by reference when set or gotten?
+
+
+ All properties as always handled by reference (except primitive types). If they are not immutable and you modify them you are affecting the bean/s that reference them too.
+
+
+*What is with the interface and implementation names in the synd and module packages?
+
+
+ Interfaces have the following naming pattern: \I. Default implementations provided with Rome are named just \. For example, SyndFeedI is the interface and SyndFeed is the default implementation.
+
+
+ We decided to use \ for the default implementation classes as we think they'll be the implementation of choice most of the time.
+
+
+*Why the beans in the synd and module packages have interface and implementation versions of them?
+
+
+ We added interfaces only for the higher abstraction layer of Rome, SyndFeed (and Modules as they are used to express extensible metadata for SyndFeed instances). The reasoning behind such decoupling was to allow facading existing classes as SyndFeed beans. For example some persistent classes. This would allow to process them through components that work with SyndFeedI.
+
+
+*Why the RSS and Atom beans don't have interface and implementation versions of it?
+
+
+ We thought about this, we dismissed the idea. The reasoning was that we expect to work with the SyndFeed and Module beans all the time and the convenience of using interface should be at that level only. We have RSS and Atom only because we have folks going and making up things without talking to each other. In short, we expect all our application processing to be done in a feed agnostic way in Java using SyndFeed and Module beans.
+
+
+*How all the escaping for the description elements is handled for the different feed types as they keep changing their mind version after version?
+
+
+ Item description MIME type, depending on the RSS version is text/plain (0.91), text/html (0.92, 0.93, 2.0) or configurable (0.94). The thing is that when you get the value out of JDOM Element it's always XML unescaped. When putting data into a JDOM Element the data is XML escaped. This is not 100% correct but it will work in most of the cases.
+
+
+ Note that type in feed beans indicate what was the escaping type of the underlying feed, but if you get the value is already unescaped.
+
+
+*How does Rome handle Atom content elements that support encoding (Base64, XML, plain) using the mode attribute?
+
+
+ The mode in feed in content indicates what was the encoding of the element in the feed, but when you get the value is already unencoded.
+
+
+*What kind of input and output Rome supports?
+
+
+ Rome implementation currently uses JDOM for parsing and generating syndication feeds. As people tend to use the XML libraries they feel more comfortable with we have built in support for SAX, DOM, JDOM, byte streams, character streams and strings.
+
+
+*What is the SyndFeedI.getSupportedFeedTypes() method for?
+
+
+ This method was originally a static method in the SyndFeed class. We've moved ot the SyndFeedI interface as we thought it would be useful to be able to ask a SyndFeedI instance the feed converters it handles.
+
+
+*Are Rome beans Serializable? Why?
+
+
+ Yes, the default bean implementations of SyndFeedI provided with Rome are Serializable.
+
+
+ However, the \*I interfaces are not. We made that decision consciously and the reason behind it is closely related to the reason we introduced the \*I interfaces. You may want to extend some existing classes to implement SyndFeedI, and these classes you are extending may not be Serializable and cannot be (for example, they are tied to a live InputStream).
+
+
+*Why all those packages?
+
+
+ TBD
+
diff --git a/src/site/apt/RomeV0.4FeedAndEntryURIMapping.apt b/src/site/apt/RomeV0.4FeedAndEntryURIMapping.apt
new file mode 100644
index 0000000..c3d1055
--- /dev/null
+++ b/src/site/apt/RomeV0.4FeedAndEntryURIMapping.apt
@@ -0,0 +1,100 @@
+ -----
+ Rome v0.4, Feed and Entry URI Mapping
+ -----
+ mkurz
+ -----
+ 2011-08-15 06:41:03.135
+ -----
+
+Rome v0.4, Feed and Entry URI Mapping
+
+
+ Rome Synd beans define the concept of URI at both feed and entry levels. The purpose of this URI is to help uniquely identifying feeds and entries when processed with Rome. This is particularly useful when a system is persisting feeds and when doing data manipulation where a primary key for the feeds or the entries is needed.
+
+
+*The Problem
+
+
+ RSS 0.90, 0.91, 0.92, 0.93 and 1.0 do not define any special element for the purposes of identifying the feed or the items other than the items link element. The channel link element cannot be used to identify the feed as its semantics is to refer to the web site that has the information being published through the feed and, if web site offers more than one feed most likely both of them will have the same feed link value.
+
+
+ RSS 0.94 and RSS 2.0 define the guid element at item level. The guid element has an overloaded meaning. If the isPermalink attribute is true, the guid value can be used also as the URL for the item instead of the link element as well as a unique ID for the item. If the isPermalink attribute is false, the guid value can be used as a unique ID for the item. However, RSS 0.94 or RSS 2.0, do not define that the value of the guid element must be an URI.
+
+
+ Atom 0.3 defines an id element at feed and entry levels. The id element is defined as an URI. The Atom specification being currently designed requires the id element to contain a normalized URI as defined by RFC 2396bis.
+
+
+ The RSS0.94 and RSS 2.0 guid element and the Atom 0.3 id element are optional elements. Because of this, they may not be present at all in feeds.
+
+
+*Rome's Solution
+
+
+ Because the concept of a URI it is not defined in all the feed formats, Rome makes an arbitrary design decision to provide the URI functionality regardless of the original (or target) feed type. The following behavior as been chosen based on expected and assumed usage pattern of feed and entry data.
+
+
+*URI Normalization
+
+
+ If the uri property of a SyndFeed or SyndEntry bean is not NULL, the getter method must return a normalized URI following the rules defined in RFC2396bis.
+
+
+**Converting from WireFeed (RSS or Atom) to SyndFeed
+
+
+ The common use case for this scenario is when consuming a feed. Because of that, for clarity purposes, when referring to the data in the WireFeed the following sections talks about elements (as in the XML feed) instead of talking of properties.
+
+
+**SyndFeed
+
+
+ None of the RSS versions define an ID at channel level. In addition to this, Rome input classes (WireFeedInput and SyndFeedInput) do not have access to the URL (if any) used to fetch the feed. Because of this Rome does not set in the SyndFeed uri property , it is left to developer to set (if needed) a URI in the feed bean.
+
+
+ In the case of Atom 0.3, if the id element is present in the feed, the SyndFeed uri property will be set with the value of the id element. If it is not present, the developer must set (if needed) a URI manually.
+
+
+***SyndEntry
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93 & RSS 1.0 if the link element is present in the item, the SyndEntry uri property will be set with the value of the link element. Otherwise the SyndEntry uri property is left as NULL and the developer must set it (if needed).
+
+
+ For RSS 0.94 & RSS 2.0 if the guid property is present in the item, the SyndEntry uri property will be set with the value of the guid element. If the guid element is not present, the SyndEntry uri property will be set with the value of the link element. If the link element is missing but the guid is present and it is flagged as a permalink, Rome will set set the SyndEntry link property with the value of the guid element (Rome is doing this because is a common practice to generated RSS 2.0 fees with guid elements marked as permalinks and without a link element).
+
+
+ For Atom 0.3 if the id element is present, the SyndEntry uri property is set with the value of the id element. If the id element is not present, the SyndEntry uri property is set with the value of the alternate link element.
+
+
+**Converting from SyndFeed to WireFeed (RSS or Atom)
+
+
+ The common use case for this scenario is when generating a feed. Because of that, for clarity purposes, when referring to the data in the WireFeed the following sections talks about elements (as in the XML feed) instead of talking of properties.
+
+
+***SyndFeed
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93, RSS 1.0 & RSS 2.0 the SyndFeed uri property is lost as there is not possible representation in the channel element for it.
+
+
+ For Atom 0.3 set the SyndFeed uri property is set as the value for the id element.
+
+
+***SyndEntry
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93 & RSS 1.0 the SyndEntry uri property is lost as there is not possible representation in the item element for it.
+
+
+ For RSS 0.94 & RSS 2.0 the SyndEntry uri property is set as the value of the guid element with permalink set to false. If the SyndEntry uri property is not set, the SyndEntry link property is set as the value of the guid element with permalink set to true. Note that if the SyndFEntry linkproperty is missing the SyndEntry uri cannot be set as the value of the link element because it cannot be assumed that the uri property is an URL.
+
+
+ Because SyndEntry instances always return a normalized URI the value of the guid elements of a generated RSS 0.94 or RSS 2.0 may differ from the values of the guid elements of the original feed.
+
+
+ For Atom 0.3 the SyndEntry uri property is set as the id element.
+
+
+ Mosh...
+
diff --git a/src/site/apt/RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.apt b/src/site/apt/RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.apt
new file mode 100644
index 0000000..1486e65
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtiliEsROMEV0.7DateAndTimeParsing.apt
@@ -0,0 +1,43 @@
+ -----
+ Rss and atOM utiliEs (ROME) v0.7 Date and Time Parsing
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:49:56.580
+ -----
+
+Rss and atOM utiliEs (ROME) v0.7 Date and Time Parsing
+
+
+ Date and time elements seem to be error prone. RSS feeds use RFC822 datetime formats and Atom feeds use W3C datetime formats. Both RFC822 and W3C support quite a few flavors for specifying date and time. Some feeds use the wrong standard (such as some RSS feeds using W3C dates). Other feeds have an ENTER before or after the date. And another feeds use an arbitrary format altogether.
+
+
+ To help cope with this ROME makes a few tricks:
+
+
+
+ * It trims datetime elements before parsing them.
+
+ * It tries both RFC822 and W3C formats in all feeds.
+
+ * It uses custom format masks (if provided) when the previous steps fail.
+
+ []
+
+*Using Custom Format Masks
+
+
+ Custom format masks can be specified in the file in any of the classpath elements.
+
+
+ The masks must be specified in the property.
+
+
+ If more than one mask is to be specified they must be separated with '|' characters.
+
+
+ The syntax for the masks is the one use by by the class. Always US Locale is assumed for the masks.
+
+
+ If datetime masks are specified in more than one file in teh classpath, they are all aggregated.
+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.apt
new file mode 100644
index 0000000..9eac566
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedAndEntryURIMappingHowSyndFeedAndSyndEntryUriPropertiesMapToRSSAndAtomElements.apt
@@ -0,0 +1,97 @@
+ -----
+ Feed and Entry URI Mapping, how SyndFeed and SyndEntry 'uri' properties map to RSS and Atom elements
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:05:43.877
+ -----
+
+Feed and Entry URI Mapping, how SyndFeed and SyndEntry 'uri' properties map to RSS and Atom elements
+
+
+ Rss and atOM utilitiEs (ROME) Synd\* beans define the concept of URI at both feed and entry levels. The purpose of this URI is to help uniquely identifying feeds and entries when processed with ROME. This is particularly useful when a system is persisting feeds and when doing data manipulation where a primary key for the feeds or the entries is needed.
+
+
+*The Problem
+
+
+ RSS 0.90, 0.91, 0.92, 0.93 and 1.0 do not define any special element for the purposes of identifying the feed or the items other than the items link element. The channel link element cannot be used to identify the feed as its semantics is to refer to the web site that has the information being published through the feed and, if web site offers more than one feed most likely both of them will have the same feed link value.
+
+
+ RSS 0.94 and RSS 2.0 define the guid element at item level. The guid element has an overloaded meaning. If the isPermalink attribute is true, the guid value can be used also as the URL for the item instead of the link element as well as a unique ID for the item. If the isPermalink attribute is false, the guid value can be used as a unique ID for the item. However, RSS 0.94 or RSS 2.0, do not define that the value of the guid element must be an URI.
+
+
+ Atom 0.3 defines an id element at feed and entry levels. The id element is defined as an URI. The Atom specification being currently designed requires the id element to contain a normalized URI as defined by RFC 2396bis.
+
+
+ The RSS0.94 and RSS 2.0 guid element and the Atom 0.3 id element are optional elements. Because of this, they may not be present at all in feeds.
+
+
+*ROME's Solution
+
+
+ Because the concept of a URI it is not defined in all the feed formats, ROME makes an arbitrary design decision to provide the URI functionality regardless of the original (or target) feed type. The following behavior as been chosen based on expected and assumed usage pattern of feed and entry data.
+
+
+*URI Normalization
+
+
+ If the uri property of a SyndFeed or SyndEntry bean is not NULL, the getter method must return a normalized URI following the rules defined in RFC2396bis.
+
+
+**Converting from WireFeed (RSS or Atom) to SyndFeed
+
+
+ The common use case for this scenario is when consuming a feed. Because of that, for clarity purposes, when referring to the data in the WireFeed the following sections talks about elements (as in the XML feed) instead of talking of properties.
+
+
+**SyndFeed
+
+
+ None of the RSS versions define an ID at channel level. In addition to this, ROME input classes (WireFeedInput and SyndFeedInput) do not have access to the URL (if any) used to fetch the feed. Because of this ROME does not set in the SyndFeed uri property , it is left to developer to set (if needed) a URI in the feed bean.
+
+
+ In the case of Atom 0.3, if the id element is present in the feed, the SyndFeed uri property will be set with the value of the id element. If it is not present, the developer must set (if needed) a URI manually.
+
+
+***SyndEntry
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93 & RSS 1.0 if the link element is present in the item, the SyndEntry uri property will be set with the value of the link element. Otherwise the SyndEntry uri property is left as NULL and the developer must set it (if needed).
+
+
+ For RSS 0.94 & RSS 2.0 if the guid property is present in the item, the SyndEntry uri property will be set with the value of the guid element. If the guid element is not present, the SyndEntry uri property will be set with the value of the link element. If the link element is missing but the guid is present and it is flagged as a permalink, ROME will set set the SyndEntry link property with the value of the guid element (ROME is doing this because is a common practice to generated RSS 2.0 fees with guid elements marked as permalinks and without a link element).
+
+
+ For Atom 0.3 if the id element is present, the SyndEntry uri property is set with the value of the id element. If the id element is not present, the SyndEntry uri property is set with the value of the lternate link element.
+
+
+**Converting from SyndFeed to WireFeed (RSS or Atom)
+
+
+ The common use case for this scenario is when generating a feed. Because of that, for clarity purposes, when referring to the data in the WireFeed the following sections talks about elements (as in the XML feed) instead of talking of properties.
+
+
+***SyndFeed
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93, RSS 1.0 & RSS 2.0 the SyndFeed uri property is lost as there is not possible representation in the channel element for it.
+
+
+ For Atom 0.3 set the SyndFeed uri property is set as the value for the id element.
+
+
+***SyndEntry
+
+
+ For RSS 0.91, RSS 0.92, RSS 0.93 & RSS 1.0 the SyndEntry uri property is lost as there is not possible representation in the item element for it.
+
+
+ For RSS 0.94 & RSS 2.0 the SyndEntry uri property is set as the value of the guid element with permalink set to false. If the SyndEntry uri property is not set, the SyndEntry link property is set as the value of the guid element with permalink set to true. Note that if the SyndFEntry linkproperty is missing the SyndEntry uri cannot be set as the value of the link element because it cannot be assumed that the uri property is an URL.
+
+
+ Because SyndEntry instances always return a normalized URI the value of the guid elements of a generated RSS 0.94 or RSS 2.0 may differ from the values of the guid elements of the original feed.
+
+
+ For Atom 0.3 the SyndEntry uri property is set as the id element.
+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.apt
new file mode 100644
index 0000000..7a781da
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/FeedsDateElementsMappingToSyndFeedAndSyndEntry.apt
@@ -0,0 +1,88 @@
+ -----
+ Feeds Date Elements Mapping to SyndFeed and SyndEntry
+ -----
+ mkurz
+ -----
+ 2011-08-15 08:59:02.075
+ -----
+
+Feeds Date Elements Mapping to SyndFeed and SyndEntry
+
+
+ The different RSS versions and Atom define different date elements at feed and entry level. Some of them also define syndication information indicating when (and when not) and how often to fetch feeds for updates. There is not always a possible mapping or conversion of this information when going from one format to another.
+
+
+ As this is still subject of debate ({{{http://www.tbray.org/ongoing/When/200x/2004/07/30/Dates}How About a Date}} and {{{http://www.intertwingly.net/wiki/pie/DateSurvey}Date Survey}}), for now, in Rss and atOM utilitiEs (ROME) we've taken a simplistic approach.
+
+
+ When handling feeds at WireFeed level, <<>> or <<>>, it is possible to access all the date elements and syndication information available in the feed.
+
+
+ When handling feeds at SyndFeed level, <<>>, there is only one date element available, the <<>>. Both, <<>> and <<>> have the <<>> property. In addition, it is possible to use the Syndication Module.
+
+
+ The mapping of the date elements from the different feed formats to SyndFeed is as follows.
+
+
+*For RSS 0.90
+
+
+ RSS 0.90 does not define date elements.
+
+
+ There is no mapping to <<>> and <<>> date properties.
+
+
+*For RSS 0.91, 0.92
+
+
+ RSS 0.91 and 0.92 define <<>> and <<>> at feed level.
+
+
+ The feed <<>> element is mapped to the <<>> <<>> property. The <<>> element is lost.
+
+
+*For RSS 0.93, 0.94 and 2.0
+
+
+ RSS 0.93, 0.94 and 2.0 define <<>> and <<>> at feed level. They also define <<>> and <<>> at item level.
+
+
+ The feed <<>> element is mapped to the <<>> <<>> property. The <<>> element is lost.
+
+
+ The item <<>> element is mapped to the <<>> <<>> property. The <<>> element is lost.
+
+
+*For RSS 1.0
+
+
+ RSS 1.0 use DC Module data at feed an item level to indicate date information about the feed and the items.
+
+
+ <<>> and <<>> use the DC Module <<>> element for the <<>> property.
+
+
+*For Atom 0.3
+
+
+ Atom 0.3 defines a <<>> element at feed level and the <<>>, <<>> & <<>> elements at entry level.
+
+
+ The feed <<>> element is mapped to the <<>> <<>> property.
+
+
+ The item <<>> element is mapped to the <<>> <<>> property. The entry elements, <<>> and <<>>, are lost.
+
+
+*For Atom 1.0
+
+
+ (Atom 1.0 supported in ROME since v0.8)
+
+
+ Atom 1.0 defines an <<>> element at the feed level, which ROME maps to <<>>.
+
+
+ Atom 1.0 defines <<>> and <<>> elements at the entry level, which ROME maps to <<>> and <<>> respectively.
+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.apt
new file mode 100644
index 0000000..e9c1d5f
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEPluginsMechanism.apt
@@ -0,0 +1,208 @@
+ -----
+ Rss and atOM utilitiEs (ROME) Plugins Mechanism
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:03:07.534
+ -----
+
+Rss and atOM utilitiEs (ROME) Plugins Mechanism
+
+
+ ROME has been designed around a plugin mechanism. All the supported feed types (RSSs and Atom) is done by plugins included in the distribution.
+
+
+ Parsing feeds, generating feeds, converting feeds from a concrete feed to a SyndFeed and vice versa, parsing modules and generating modules is done using plugins.
+
+
+ Plugins for new functionality can be added and default plugins can be easily replaced with alternate plugins.
+
+
+*Plugins definition files
+
+
+ Plugins are defined in a properties file, the <<>> file.
+
+
+ The default plugins definition file is included in the ROME JAR file, <<>>, this is the first plugins definition file to be processed. It defines the default parsers, generators and converters for feeds and modules ROME provides.
+
+
+ After loading the default plugins definition file, ROME looks for additional plugins definition files in all the CLASSPATH entries, this time at root level, <<>>. And appends the plugins definitions to the existing ones. Note that if there are several <<>> files in the different CLASSPATH entries all of them are processed. The order of processing depends on how the <<>> processes the CLASSPATH entries, this is normally done in the order of appearance \-of the entry\- in the CLASSPATH.
+
+
+ For each type of plugin (parser, generator, converter, ect) a list of available plugins is built following the read order just described. The plugins classes are then loaded and instantiated. All plugins have some kind of primary key. In the case or parsers, generators and converters the primary key is the type of feed they handle. In the case of modules, the primary key is the module URI. If a plugin list definition (the aggregation of all the plugins of the same time from all the <<>>) contains more than one plugin with the same primary key, the latter one is the one that will be used(this enables replacing default plugins with custom ones).
+
+
+ The plugins are read, loaded and managed by the implementation class <<>>. This class is an abstract class and it is extended to provide support for each type of plugin.
+
+
+*Parser Plugins
+
+
+ Parser plugins are managed by the <<>> class (subclass of the <<>>). This plugin manager looks for the <<>> property in all the <<>> files. The fully qualified names of the parser classes must be separated by whitespaces or commas. For example, the default <<>> file parser plugins definition is as follows:
+
+
+
++------+
+
+# Feed Parser implementation classes
+#
+WireFeedParser.classes=com.sun.syndication.io.impl.RSS090Parser \
+ com.sun.syndication.io.impl.RSS091NetscapeParser \
+ com.sun.syndication.io.impl.RSS091UserlandParser \
+ com.sun.syndication.io.impl.RSS092Parser \
+ com.sun.syndication.io.impl.RSS093Parser \
+ com.sun.syndication.io.impl.RSS094Parser \
+ com.sun.syndication.io.impl.RSS10Parser \
+ com.sun.syndication.io.impl.RSS20wNSParser \
+ com.sun.syndication.io.impl.RSS20Parser \
+ com.sun.syndication.io.impl.Atom03Parser
+
++------+
+
+ All the classes defined in this property have to implement the <<>> interface. Parser instances must be thread safe. The return value of the <<>> method is used as the primary key. If more than one parser returns the same type, the latter one prevails.
+
+
+*Generator Plugins
+
+
+ Generator plugins are managed by the <<>> class (subclass of the <<>>). This plugin manager looks for the <<>> property in all the <<>> files. The fully qualified names of the generator classes must be separated by whitespaces or commas. For example, the default <<>> file generator plugins definition is as follows:
+
+
+
++------+
+
+# Feed Generator implementation classes
+#
+WireFeedGenerator.classes=com.sun.syndication.io.impl.RSS090Generator \
+ com.sun.syndication.io.impl.RSS091NetscapeGenerator \
+ com.sun.syndication.io.impl.RSS091UserlandGenerator \
+ com.sun.syndication.io.impl.RSS092Generator \
+ com.sun.syndication.io.impl.RSS093Generator \
+ com.sun.syndication.io.impl.RSS094Generator \
+ com.sun.syndication.io.impl.RSS10Generator \
+ com.sun.syndication.io.impl.RSS20Generator \
+ com.sun.syndication.io.impl.Atom03Generator
+
++------+
+
+ All the classes defined in this property have to implement the <<>> interface. Generator instances must be thread safe. The return value of the <<>> method is used as the primary key. If more than one generator returns the same type, the latter one prevails.
+
+
+*Converter Plugins
+
+
+ Converter plugins are managed by the <<>> class (subclass of the <<>>). This plugin manager looks for the <<>> property in all the <<>> files. The fully qualified names of the converter classes must be separated by whitespaces or commas. For example, the default <<>> file converter plugins definition is as follows:
+
+
+
++------+
+
+# Feed Conversor implementation classes
+#
+Converter.classes=com.sun.syndication.feed.synd.impl.ConverterForAtom03 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS090 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS091Netscape \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS091Userland \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS092 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS093 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS094 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS10 \
+ com.sun.syndication.feed.synd.impl.ConverterForRSS20
+
++------+
+
+ All the classes defined in this property have to implement the <<>> interface. Converter instances must be thread safe. The return value of the <<>> method is used as the primary key. If more than one converter returns the same type, the latter one prevails.
+
+
+*Module Plugins
+
+
+ There are 2 types of module plugins, module parser plugins and module generator plugins. They use a same pattern feed parsers and generators use.
+
+
+ The main difference is that support for module plugins has to be wired in the feed parser and generator plugins. The default feed parser and generator plugins supporting module plugins are: RSS 1.0, RSS 2.0 and Atom 0.3.
+
+
+ It is important to understand that this wiring is for modules support. Once a feed parser or generator has modules support, new modules can be used just by adding them to right property in the <<>> file. No code changes are required.
+
+
+ Module parsers and generators are defined at feed and item level. This allow selective handling of modules, for example handling Syndication module at feed level only.
+
+
+ Module parser plugins are managed by the <<>> class (subclass of the <<>>). This plugin manager looks for the <<<.feed.ModuleParser.classes>>> and the <<<.item.ModuleParser.classes>>> properties in all the <<>> files. must be the type defined by the parser (ie: rss_1.0, atom_0.3). The fully qualified names of the module parser classes must be separated by whitespaces or commas. For example, the default <<>> file modules parser plugins definition is as follows:
+
+
+
++------+
+
+# Parsers for Atom 0.3 feed modules
+#
+atom_0.3.feed.ModuleParser.classes=com.sun.syndication.io.impl.SyModuleParser \
+ com.sun.syndication.io.impl.DCModuleParser
+
+# Parsers for Atom 0.3 entry modules
+#
+atom_0.3.item.ModuleParser.classes=com.sun.syndication.io.impl.DCModuleParser
+
+# Parsers for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleParser.classes=com.sun.syndication.io.impl.SyModuleParser \
+ com.sun.syndication.io.impl.DCModuleParser
+
+# Parsers for RSS 1.0 item modules
+#
+rss_1.0.item.ModuleParser.classes=com.sun.syndication.io.impl.DCModuleParser
+
+# Parsers for RSS 2.0 feed modules
+#
+rss_2.0.feed.ModuleParser.classes=
+
+# Parsers for RSS 2.0 item modules
+#
+rss_2.0.item.ModuleParser.classes=
+
++------+
+
+ All the classes defined in this property have to implement the <<>> interface. ModuleParser instances must be thread safe. The return value of the <<>> method is used as the primary key. If more than one module parser returns the same URI, the latter one prevails.
+
+
+ Module generator plugins are managed by the <<>> class (subclass of the <<>>). This plugin manager looks for the <<<.feed.ModuleGenerator.classes>>> and the <<<.item.ModuleGenerator.classes>>> properties in all the <<>> files. must be the type defined by the generator (ie: rss_1.0, atom_0.3). The fully qualified names of the module generator classes must be separated by whitespaces or commas. For example, the default <<>> file modules generator plugins definition is as follows:
+
+
+
++------+
+
+# Generators for Atom 0.3 feed modules
+#
+atom_0.3.feed.ModuleGenerator.classes=com.sun.syndication.io.impl.SyModuleGenerator \
+ com.sun.syndication.io.impl.DCModuleGenerator
+
+# Generators for Atom 0.3 entry modules
+#
+atom_0.3.item.ModuleGenerator.classes=com.sun.syndication.io.impl.DCModuleGenerator
+
+# Generators for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleGenerator.classes=com.sun.syndication.io.impl.SyModuleGenerator \
+ com.sun.syndication.io.impl.DCModuleGenerator
+
+# Generators for RSS_1.0 entry modules
+#
+rss_1.0.item.ModuleGenerator.classes=com.sun.syndication.io.impl.DCModuleGenerator
+
+# Generators for RSS 2.0 feed modules
+#
+rss_2.0.feed.ModuleGenerator.classes=
+
+# Generators for RSS_2.0 entry modules
+#
+rss_2.0.item.ModuleGenerator.classes=
+
++------+
+
+ All the classes defined in this property have to implement the <<>> interface. ModuleGenerator instances must be thread safe. The return value of the <<>> method is used as the primary key. If more than one module generator returns the same URI, the latter one prevails.
+
+
+ See also: a step\-by\-step {{{./RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.html}tutorial for implementing a custom module}}.
+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5HowToBuildAndRunTheTutorialsSampleCode.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5HowToBuildAndRunTheTutorialsSampleCode.apt
new file mode 100644
index 0000000..7734b44
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5HowToBuildAndRunTheTutorialsSampleCode.apt
@@ -0,0 +1,87 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5, How to build and run the tutorials sample code
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:41:55.286
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5, How to build and run the tutorials sample code
+
+
+ These instructions are outdated
+
+
+*Building the samples with Maven
+
+
+ This is, as usual, the easiest way.
+
+
+ There's only one configuration step: Maven downloads dependencies from an online repository (by default ibiblio), to a local repository (on UNIX usually in \~/.maven/repository). Because the rome distribution is not yet on ibiblio, you need to add it yourself, either to your local repository, or to your own intranet maven repository if you have such a thing in your organization.
+
+
+ If you built ROME run maven jar:install in the rome project to install ROME's jar in your Maven repository.
+
+
+ If you got ROME binary distribution copy the ROME's jar file to your Maven repository (on UNIX that would be <<>>).
+
+
+ Then building the samples it's easy as a pie, just run maven jar in the samples sub\-project and you are all set.
+
+
+ To build the sample Web Application, just run maven war in the samples sub\-project. The WAR file, <<>>, will be created under the <<>> directory.
+
+
+*Building the samples with Ant
+
+
+ The targets present in the build.xml are very helpful, ant get\-deps will download from ibiblio to rome\-samples/target/lib all the jar files ROME depends on and are needed for building an application using Rome.
+
+
+ In order to build the samples (or any subprojects), you'll need to first ensure that rome itself is built. You can do this simply by running ant in the project root directory.
+
+
+ Once this is done, change to the samples directory, and just run ant. This will produce two files, rome\-samples.jar which contains the sample applications, and rome\-samples.war which will contain a deployable web application war file for the FeedServlet sample.
+
+
+*Running the samples with Maven
+
+
+ The Maven goals for running the samples are defined in maven.xml.
+
+
+
+ * <<>> runs the FeedAggregator sample
+
+ * <<>> runs the FeedConverter sample
+
+ * <<>> runs the FeedReader sample
+
+ * <<>> runs the FeedWriter sample
+
+ * <<>> runs the FeedConverter sample against a file with Sample Module data (shows off custom module plugin)
+
+ []
+
+ To run the sample Web Application you'll need to deploy the WAR file into your servlet container. If you are using Tomcat 4 or Tomcat 5 and the WAR file was dropped in the <<<$\{TOMCAT\}/webapps>>> directory the URL for the <<>> would be {{{http://localhost:8080/rome\-samples/feed}http://localhost:8080/rome\-samples/feed}} in a default localhost Tomcat installation.
+
+
+*Running the samples with Ant
+
+
+ All ant targets for the samples generate the same file named toto: feel free to customize this build.xml to your own needs. Also today all these targets depends on the jar target, which represents some overhead if you have already built. Get rid of that once your project is well setup.
+
+
+
+ * <<>> runs the FeedAggregator sample
+
+ * <<>> runs the FeedConverter sample
+
+ * <<>> runs the FeedReader sample
+
+ * <<>> runs the FeedWriter sample
+
+ * <<>> runs the FeedConverter sample against a file with Sample Module data (shows off custom module plugin)
+
+ []
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.apt
new file mode 100644
index 0000000..d964a36
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialDefiningACustomModuleBeanParserAndGenerator.apt
@@ -0,0 +1,369 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Defining a Custom Module (bean, parser and generator)
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:29:19.297
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Defining a Custom Module (bean, parser and generator)
+
+
+ <> Synd J2SE 1.4\+, JDOM 1.0 and ROME 0.5.
+
+
+ This tutorial walks through the steps of creating a custom module for syndication feeds that support additional namespaces (such as RSS 1.0, RSS 2.0 and Atom 0.3).
+
+
+ To understand this tutorial you should be familiar the with ROME API and with the use of modules in syndication feeds.
+
+
+ Out of the box ROME parsers and generators support plug\-ability of modules for RSS 1.0, RSS 2.0 and Atom 0.3 at both feed and item/entry levels. Also support for the Dublin Core and Syndication modules is provided.
+
+
+ The complete source for this tutorial is in the ROME samples bundle as well as in CVS.
+
+
+*What is the intended outcome of the tutorial?
+
+
+ The goal is to add support for a hypothetical Sample Module by defining a module bean, module parser and module generator and the necessary configuration to wire the parser and generator to an RSS 1.0 parser and RSS 1.0 generator.
+
+
+ The sample module defines 3 elements, 'bar', 'foo' and 'date', where 'bar' and 'date' may occur at most once and the 'foo' element may occur several times. For example, a feed with the Sample Module data would look like:
+
+
+
++------+
+
+
+
+
+ RSS 1.0 Feed with Sample Module
+ http://rome.dev.java.net
+ This is a feed showing how to use a custom module with ROME
+
+
+
+
+
+
+ Channel bar
+ Channel first foo
+ Channel second foo
+
+
+ Title of Item 01
+ http://rome.dev.java.net/item01
+ Item 01 does not have Sample module data
+
+
+ Title of Item 02
+ http://rome.dev.java.net/item02
+ Item 02 has Sample module data
+ Item 02 bar
+ Item 02 only foo
+ 2004-07-27T00:00+00:00
+
+
+
++------+
+
+*Sample Module Bean
+
+
+ First we must start with the bean interface, SampleModule. SampleModule must extend Module. The Module interface defines the getUri() method, which will return a URI identifying the module.
+
+
+ The Module interface also extends the CopyFrom interface to enable copying properties from alternate implementations of the concrete Module interface. More on this later in this page.
+
+
+ The SampleModule's URI is defined as a constant, accessible via the getURI() instance method. This is for convenience and good practice only.
+
+
+ Then the module defines 3 properties: bar (String), foos (List) and date (Date). The elements of the foos property list must be strings (wishing for Java 5 generics already?).
+
+
+
++------+
+
+public interface SampleModule extends Module {
+
+ public static final String URI = "http://rome.dev.java.net/module/sample/1.0";
+
+ public String getBar();
+ public void setBar(String bar);
+
+ public List getFoos();
+ public void setFoos(List foos);
+
+ public Date getDate();
+ public void setDate(Date date);
+}
+
++------+
+
+ Next we have to write the bean implementation, SampleModuleImpl.
+
+
+ SampleModuleImpl extends ModuleImpl. ModuleImpl is the default implementation of the \=\=Module interface. ModuleImpl automatically provides equals, hashCode, toString and clone support for the properties of the class given in the constructor (SampleModule). Also the URI of the Sample module is indicated; it will be used by the Module.getUri() method.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ ...
+ public SampleModuleImpl() {
+ super(SampleModule.class,SampleModule.URI);
+ }
+
+ public String getBar() {
+ return _bar;
+ }
+ [...]
+
++------+
+
+ The module properties are just Java Bean properties. The only catch is to follow ROME semantics for Collection properties: in the case of a null value for the collection, an empty collection must be returned. Also, following ROME semantics, all properties are by reference, including mutable ones.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ private String _bar;
+ private List _foos;
+ private Date _date;
+ ...
+ public void setBar(String bar) {
+ _bar = bar;
+ }
+
+ public List getFoos() {
+ return (_foos==null) ? (_foos=new ArrayList()) : _foos;
+ }
+
+ public void setFoos(List foos) {
+ _foos = foos;
+ }
+
+ public Date getDate() {
+ return _date;
+ }
+
+ public void setDate(Date date) {
+ _date = date;
+ }
+
++------+
+
+*The CopyFrom interface
+
+
+ Now the weird part, the bits for the CopyFrom logic. The {{{./TheCopyFromInterface.html}The CopyFrom interface (rome)}} document fully explains the CopyFrom logic in detail. In short, the CopyFrom interface is to support copying properties from one implementation of a bean (defined through an interface) to another implementation of the same bean.
+
+
+ The getInterface() method returns the bean interface of the implementation (this is necessary for collections containing sub\-classes such as a list of modules).
+
+
+ The copyFrom() method copies all the properties from the parameter object (which must be a SampleModule implementation) into the caller bean properties. Note that the copyFrom must do a deep copy.
+
+
+
++------+
+
+public class SampleModuleImpl extends ModuleImpl implements SampleModule {
+ ...
+ public Class getInterface() {
+ return SampleModule.class;
+ }
+
+ public void copyFrom(Object obj) {
+ SampleModule sm = (SampleModule) obj;
+ setBar(sm.getBar());
+ List foos = new ArrayList(sm.getFoos()); // this is enough for the copy because the list elements are inmutable (Strings)
+ setFoos(foos);
+ setDate((Date)sm.getDate().clone()); // because Date is not inmutable.
+ }
+
+}
+
++------+
+
+*Sample Module Parser
+
+
+ The sample module parser must implement the ModuleParser interface. This interface defines 2 methods, getNamespaceUri() that returns the URI of the module and parse(Element) which extracts the module elements from the given Element.
+
+
+ The feed parsers will invoke the module parser with a feed element or with an item element. The module parser must look for module elements in the children of the given element. That is was the Sample parser is doing when looking for 'bar', 'foo' and 'date' children elements in the received element.
+
+
+ In the case of the 'foo' element it looks for all occurrences as the Sample module schema allows for more than one occurrence of the 'foo' element. A SampleModule bean is created and the found values are set into it. For the 'date' element it assumes its a date value in W3C datetime format.
+
+
+ If no Sample Module elements are found in the feed, the parse(Element) method returns null. This is to avoid having an empty instance of a module \-not present in the feed\- in the feed bean or in the item bean.
+
+
+
++------+
+
+public class SampleModuleParser implements ModuleParser {
+
+ private static final Namespace SAMPLE_NS = Namespace.getNamespace("sample", SampleModule.URI);
+
+ public String getNamespaceUri() {
+ return SampleModule.URI;
+ }
+
+ public Module parse(Element dcRoot) {
+ boolean foundSomething = false;
+ SampleModule fm = new SampleModuleImpl();
+
+ Element e = dcRoot.getChild("bar", SAMPLE_NS);
+ if (e != null) {
+ foundSomething = true;
+ fm.setBar(e.getText());
+ }
+ List eList = dcRoot.getChildren("foo", SAMPLE_NS);
+ if (eList.size() > 0) {
+ foundSomething = true;
+ fm.setFoos(parseFoos(eList));
+ }
+ e = dcRoot.getChild("date", SAMPLE_NS);
+ if (e != null) {
+ foundSomething = true;
+ fm.setDate(DateParser.parseW3CDateTime(e.getText()));
+ }
+ return (foundSomething) ? fm : null;
+ }
+
+ private List parseFoos(List eList) {
+ List foos = new ArrayList();
+ for (int i = 0; i < eList.size(); i++) {
+ Element e = (Element) eList.get(i);
+ foos.add(e.getText());
+ }
+ return foos;
+ }
+
+}
+
++------+
+
+*Sample Module Generator
+
+
+ The sample module generator must implement the ModuleGenerator interface. This interface defines 2 methods, getNamespaceUri() that returns the URI of the module and generate(ModuleI,Element) which injects the module data into the given Element.
+
+
+ The feed generator will invoke the module generator with a feed element or with an item element. The module generator must inject the module properties into the given element (which is a feed or an item). This injection has to be done using the right namespace. The set of namespaces returned by the getNamespaces() method will be used to declare the namespaces used by the module in the feed root element.
+
+
+ If no Sample Module bean is in the feed bean the module generator is not invoked at all.
+
+
+
++------+
+
+public class SampleModuleGenerator implements ModuleGenerator {
+ private static final Namespace SAMPLE_NS = Namespace.getNamespace("sample", SampleModule.URI);
+
+ public String getNamespaceUri() {
+ return SampleModule.URI;
+ }
+
+ private static final Set NAMESPACES;
+
+ static {
+ Set nss = new HashSet();
+ nss.add(SAMPLE_NS);
+ NAMESPACES = Collections.unmodifiableSet(nss);
+ }
+
+ public Set getNamespaces() {
+ return NAMESPACES;
+ }
+
+ public void generate(Module module, Element element) {
+
+ // this is not necessary, it is done to avoid the namespace definition in every item.
+ Element root = element;
+ while (root.getParent()!=null && root.getParent() instanceof Element) {
+ root = (Element) element.getParent();
+ }
+ root.addNamespaceDeclaration(SAMPLE_NS);
+
+ SampleModuleI fm = (SampleModule)module;
+ if (fm.getBar() != null) {
+ element.addContent(generateSimpleElement("bar", fm.getBar()));
+ }
+ List foos = fm.getFoos();
+ for (int i = 0; i < foos.size(); i++) {
+ element.addContent(generateSimpleElement("foo",foos.get(i).toString()));
+ }
+ if (fm.getDate() != null) {
+ element.addContent(generateSimpleElement("date", DateParser.formatW3CDateTime(fm.getDate())));
+ }
+ }
+
+ protected Element generateSimpleElement(String name, String value) {
+ Element element = new Element(name, SAMPLE_NS);
+ element.addContent(value);
+ return element;
+ }
+
+}
+
++------+
+
+*Configuration to make ROME process Sample Module in feeds
+
+
+ The last step is to setup the configuration file to indicate to ROME how and when to use the Sample Module parser and generator.
+
+
+ The configuration is stored in a Properties file, 'rome.properties', that has to be in the root of the classpath or JAR where the Sample Module bean, parser and generator classes are.
+
+
+ You must indicate the syndication feed formats (ie RSS 1.0) that must be aware of the Sample Module. You must indicate if the Sample Module is available for feed or item elements, or for both. You must indicate both the parser and the generator classes.
+
+
+ Following is the 'rome.properties' file for the Sample Module, it's defined for RSS 1.0 only, for both feed and item elements.
+
+
+
++------+
+
+# Parsers for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleParser.classes=com.sun.syndication.samples.module.SampleModuleParser
+
+# Parsers for RSS 1.0 item modules
+#
+rss_1.0.item.ModuleParser.classes=com.sun.syndication.samples.module.SampleModuleParser
+
+# Generators for RSS 1.0 feed modules
+#
+rss_1.0.feed.ModuleGenerator.classes=com.sun.syndication.samples.module.SampleModuleGenerator
+
+# Generators for RSS_1.0 entry modules
+#
+rss_1.0.item.ModuleGenerator.classes=com.sun.syndication.samples.module.SampleModuleGenerator
+
++------+
+
+ If you are defining more than one module, indicate the parser and generator implementation classes separated by commas or spaces.
+
+
+*Using the Sample Module from the SyndFeed beans
+
+
+ They will be there, just use them. You may get the SampleModule bean using the getModule(String Uri) method of the SyndFeed bean and the SyndEntry bean.
+
+
+ Adding or replacing a syndication feed parser, generator or converter goes along the same lines of what it has been explained in the tutorial for modules. This is explained in the {{{./RssAndAtOMUtilitiEsROMEPluginsMechanism.html}ROME Plugins Mechanism}} topic.
+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToAggregateManySyndicationFeedsIntoASingleOne.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToAggregateManySyndicationFeedsIntoASingleOne.apt
new file mode 100644
index 0000000..48171a5
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToAggregateManySyndicationFeedsIntoASingleOne.apt
@@ -0,0 +1,146 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to aggregate many syndication feeds into a single one
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:12:26.866
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to aggregate many syndication feeds into a single one
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and ROME 0.5.
+
+
+ ROME represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with ROME are all lightweight classes.
+
+
+ ROME includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using ROME are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the InputStream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ ROME also includes generators to create syndication feeds out of SyndFeed instances. The SyndFeedOutput class does this generation. The SyndFeedOutput will generate a syndication feed of the feed type indicated by the SyndFeed object being output. The following two lines of code show how to create a syndication feed output from a SyndFeed instance:
+
+
+
++------+
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,new PrintWriter(System.out));
+
++------+
+
+ The first line creates a SyndFeedOutput instance that will produce syndication feeds. It can output feeds of any type (rss_0.9, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0 & atom_0.3), the SyndFeed feedType property indicates the type. The second line writes the SyndFeed as a syndication feed into the application's output.
+
+
+ SyndFeed instances can also be created and populated within the code. For example:
+
+
+
++------+
+
+SyndFeed aggrFeed = new SyndFeedImpl();
+aggrFeed.setFeedType("rss_1.0");
+aggrFeed.setTitle("Aggregated Feed");
+aggrFeed.setDescription("Anonymous Aggregated Feed");
+aggrFeed.setAuthor("anonymous");
+aggrFeed.setLink("http://www.anonymous.com");
+
++------+
+
+ The snipped of code above creates a SyndFeed instance using the default implementation provided by ROME, sets the feed type to RSS 1.0, sets the title, description, author and link properties of the feed.
+
+
+ SyndFeed properties can be modified, assigned to other SyndFeed instances, removed, etc. It's important to remember that the getters/setters semantics defined for all SyndFeed properties (and properties of its properties) is a copy by reference, not by value. In other words if you alter the property of a SyndFeed property you are altering the SyndFeed. Or, another example, if you assign the list of entries of one SyndFeed instance to another SyndFeed isntance and then you modify the list or any of the entries in the list, you are modifying the entries of both SyndFeed instances.
+
+
+ The following lines of code show how to copy the entries of a SyndFeed instance being read (inFeed) into a SyndFeed instance being created within the application (feed):
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.ArrayList;
+
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.feed.synd.SyndFeedImpl;
+import com.sun.syndication.io.SyndFeedOutput;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It aggregates a list of RSS/Atom feeds (they can be of different types)
+ * into a single feed of the specified type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedAggregator {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length>=2) {
+ try {
+ String outputType = args[0];
+
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(outputType);
+
+ feed.setTitle("Aggregated Feed");
+ feed.setDescription("Anonymous Aggregated Feed");
+ feed.setAuthor("anonymous");
+ feed.setLink("http://www.anonymous.com");
+
+ List entries = new ArrayList();
+ feed.setEntries(entries);
+
+ for (int i=1;i> Synd J2SE 1.4\+, JDOM 1.0 and ROME 0.5.
+
+
+ ROME represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with ROME are all lightweight classes.
+
+
+ ROME includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using ROME are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the InputStream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ ROME also includes generators to create syndication feeds out of SyndFeed instances. The SyndFeedOutput class does this generation. The SyndFeedOutput will generate a syndication feed of the feed type indicated by the SyndFeed object being output. The following two lines of code show how to create a syndication feed output from a SyndFeed instance:
+
+
+
++------+
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,new PrintWriter(System.out));
+
++------+
+
+ The first line creates a SyndFeedOutput instance that will produce syndication feeds. It can output feeds of any type (rss_0.9, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0 & atom_0.3), the SyndFeed feedType property indicates the type. The second line writes the SyndFeed as a syndication feed into the application's output.
+
+
+ Following is the full code for a Java application that reads a syndication feed and converts it to other syndication feed type, writing the converted feed to the application's output.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.SyndFeedOutput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It Converts any RSS/Atom feed type to a an RSS/Atom feed of the
+ * specified type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedConverter {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==2) {
+ try {
+ String outputType = args[0];
+
+ URL feedUrl = new URL(args[1]);
+
+ SyndFeedInput input = new SyndFeedInput();
+ SyndFeed feed = input.build(new XmlReader(feedUrl));
+ feed.setFeedType(outputType);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,new PrintWriter(System.out));
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedConverter converts between syndication feeds types.");
+ System.out.println("The first parameter must be the feed type to convert to.");
+ System.out.println(" [valid values are: rss_0.9, rss_0.91, rss_0.92, rss_0.93, ]");
+ System.out.println(" [ rss_0.94, rss_1.0, rss_2.0 & atom_0.3 ]");
+ System.out.println("The second parameter must be the URL of the feed to convert.");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToCreateAndWriteASyndicationFeed.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToCreateAndWriteASyndicationFeed.apt
new file mode 100644
index 0000000..13b8060
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToCreateAndWriteASyndicationFeed.apt
@@ -0,0 +1,204 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to create and write a syndication feed
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:20:35.352
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to create and write a syndication feed
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and ROME 0.5.
+
+
+ ROME represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with ROME are all lightweight classes.
+
+
+ Creating a feed with SyndFeed beans consists of creating beans and setting their properties. The following code fragments show how a SyndFeed bean with 3 entries is created.
+
+
+ First the SyndFeed instance is created, the preferred syndication format is set and the feed header info (title, link, description) is also set.
+
+
+
++------+
+
+SyndFeed feed = new SyndFeedImpl();
+feed.setFeedType(feedType);
+
+feed.setTitle("Sample Feed (created with ROME)");
+feed.setLink("http://rome.dev.java.net");
+feed.setDescription("This feed has been created using ROME (Java syndication utilities");
+
++------+
+
+ Then a list for entries is created, entries are created and added to the list. Each entry is set with a title, link, published date and a description. The description for the first entry is plain test, for the third entry is HTML. After each entry is created is added to the list.
+
+
+
++------+
+
+List entries = new ArrayList();
+SyndEntry entry;
+SyndContent description;
+
+entry = new SyndEntryImpl();
+entry.setTitle("ROME v1.0");
+entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+description = new SyndContentImpl();
+description.setType("text/plain");
+description.setValue("Initial release of ROME");
+entry.setDescription(description);
+entries.add(entry);
+[...]
+entry = new SyndEntryImpl();
+entry.setTitle("ROME v3.0");
+entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
+entry.setPublishedDate(DATE_PARSER.parse("2004-07-27"));
+description = new SyndContentImpl();
+description.setType("text/html");
+description.setValue("
More Bug fixes, mor API changes, some new features and some Unit testing
");
+entry.setDescription(description);
+entries.add(entry);
+
++------+
+
+ Finally the list with entries is added to the SyndFeed bean.
+
+
+
++------+
+
+feed.setEntries(entries);
+
++------+
+
+ The SyndFeed bean is now ready to be written out to a syndication feed XML document. Note that any of supported syndication formats can be set in the feedType property.
+
+
+ ROME includes generators that allow producing syndication feed XML documents from SyndFeed instances. The SyndFeedOutput class handles the generation of the syndication feed XML documents on any of the supported feed formats (RSS and Atom). The developer does not need to worry about selecting the right generator for a syndication feed, the SyndFeedOutput will take care of it by looking at the information in the SyndFeed bean. All it takes to write a syndication feed XML document using ROME \-assuming you have a SyndFeed bean and a Writer instance\- are the following lines of code:
+
+
+
++------+
+
+SyndFeed feed = ...;
+Writer writer = ...;
+
+SyndFeedOutput output = new SyndFeedOutput();
+output.output(feed,writer);
+
++------+
+
+ First a SyndFeedOutput instance is created, this instance will work with any syndication feed type (RSS and Atom versions). Then the feed and the writer are given to the SyndFeedOutput instance, the SyndFeedOutput will write the syndication feed XML document represented by the SyndFeed bean to the Writer stream.
+
+
+ Following is the full code for a Java application that creates a syndication feed and writes it to a file in the specified syndication format.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import java.io.FileWriter;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * It creates a feed and writes it to a file.
+ *
+ *
+ */
+public class FeedWriter {
+
+ private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==2) {
+ try {
+ String feedType = args[0];
+ String fileName = args[1];
+
+ SyndFeed feed = new SyndFeedImpl();
+ feed.setFeedType(feedType);
+
+ feed.setTitle("Sample Feed (created with ROME)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using ROME (Java syndication utilities");
+
+ List entries = new ArrayList();
+ SyndEntry entry;
+ SyndContent description;
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("ROME v1.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Initial release of ROME");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("ROME v2.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Bug fixes, minor API changes and some new features");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("ROME v3.0");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
+ entry.setPublishedDate(DATE_PARSER.parse("2004-07-27"));
+ description = new SyndContentImpl();
+ description.setType("text/html");
+ description.setValue("
More Bug fixes, mor API changes, some new features and some Unit testing
");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ feed.setEntries(entries);
+
+ Writer writer = new FileWriter(fileName);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,writer);
+ writer.close();
+
+ System.out.println("The feed has been written to the file ["+fileName+"]");
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedWriter creates a RSS/Atom feed and writes it to a file.");
+ System.out.println("The first parameter must be the syndication format for the feed");
+ System.out.println(" (rss_0.90, rss_0.91, rss_0.92, rss_0.93, rss_0.94, rss_1.0 rss_2.0 or atom_0.3)");
+ System.out.println("The second parameter must be the file name for the feed");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToReadASyndicationFeed.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToReadASyndicationFeed.apt
new file mode 100644
index 0000000..09fd997
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToReadASyndicationFeed.apt
@@ -0,0 +1,93 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to read a syndication feed
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:08:56.262
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME to read a syndication feed
+
+
+ <> J2SE 1.4\+, JDOM 1.0 and ROME 0.5.
+
+
+ ROME represents syndication feeds (RSS and Atom) as instances of the com.sun.syndication.synd.SyndFeed interface. The SyndFeed interfaces and its properties follow the Java Bean patterns. The default implementations provided with ROME are all lightweight classes.
+
+
+ ROME includes parsers to process syndication feeds into SyndFeed instances. The SyndFeedInput class handles the parsers using the correct one based on the syndication feed being processed. The developer does not need to worry about selecting the right parser for a syndication feed, the SyndFeedInput will take care of it by peeking at the syndication feed structure. All it takes to read a syndication feed using ROME are the following 2 lines of code:
+
+
+
++------+
+
+SyndFeedInput input = new SyndFeedInput();
+SyndFeed feed = input.build(new XmlReader(feedUrl));
+
++------+
+
+ The first line creates a SyndFeedInput instance that will work with any syndication feed type (RSS and Atom versions). The second line instructs the SyndFeedInput to read the syndication feed from the char based input stream of a URL pointing to the feed. The XmlReader is a character based Reader that resolves the encoding following the HTTP MIME types and XML rules for it. The SyndFeedInput.build() method returns a SyndFeed instance that can be easily processed.
+
+
+ The default SyndFeed implementation has a detailed and clear toString() implementation. The following line just prints it to the application's output.
+
+
+
++------+
+
+ System.out.println(feed);
+
++------+
+
+ Following is the full code for a Java application that reads a syndication feed and prints the SyndFeed bean to the application's output.
+
+
+
++------+
+
+package com.sun.syndication.samples;
+
+import java.net.URL;
+import java.io.InputStreamReader;
+import com.sun.syndication.feed.synd.SyndFeed;
+import com.sun.syndication.io.SyndFeedInput;
+import com.sun.syndication.io.XmlReader;
+
+/**
+ * It Reads and prints any RSS/Atom feed type.
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedReader {
+
+ public static void main(String[] args) {
+ boolean ok = false;
+ if (args.length==1) {
+ try {
+ URL feedUrl = new URL(args[0]);
+
+ SyndFeedInput input = new SyndFeedInput();
+ SyndFeed feed = input.build(new XmlReader(feedUrl));
+
+ System.out.println(feed);
+
+ ok = true;
+ }
+ catch (Exception ex) {
+ ex.printStackTrace();
+ System.out.println("ERROR: "+ex.getMessage());
+ }
+ }
+
+ if (!ok) {
+ System.out.println();
+ System.out.println("FeedReader reads and prints any RSS/Atom feed type.");
+ System.out.println("The first parameter must be the URL of the feed to read.");
+ System.out.println();
+ }
+ }
+
+}
+
++------+
diff --git a/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEWithinAServletToCreateAndReturnAFeed.apt b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEWithinAServletToCreateAndReturnAFeed.apt
new file mode 100644
index 0000000..b6451e2
--- /dev/null
+++ b/src/site/apt/RssAndAtOMUtilitiEsROMEV0.5AndAboveTutorialsAndArticles/RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEWithinAServletToCreateAndReturnAFeed.apt
@@ -0,0 +1,242 @@
+ -----
+ Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME within a Servlet to create and return a feed
+ -----
+ mkurz
+ -----
+ 2011-08-15 09:34:50.713
+ -----
+
+Rss and atOM utilitiEs (ROME) v0.5 Tutorial, Using ROME within a Servlet to create and return a feed
+
+
+ <> J2SE 1.4\+, Servlet Container 2.3\+, JDOM 1.0 and ROME 0.5.
+
+
+ This sample consists of a servlet that serves a feed as response. The feed type (RSS in any of its variants or Atom) can be specified as a URL parameter when requesting the feed. The returned feed is hardwired in the sample and it would be straight forward to modify the sample to generate the feed dynamically (i.e. from data stored in a database).
+
+
+ The core logic of the <<>> is in the following fragment of code:
+
+
+
++------+
+
+public class FeedServlet extends HttpServlet {
+ ...
+
+ public void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
+ ...
+ SyndFeed feed = getFeed(req);
+
+ String feedType = req.getParameter(FEED_TYPE);
+ feedType = (feedType!=null) ? feedType : _defaultFeedType;
+ feed.setFeedType(feedType);
+
+ res.setContentType(MIME_TYPE);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,res.getWriter());
+ ...
+ }
+
+ protected SyndFeed getFeed(HttpServletRequest req) throws IOException,FeedException {
+ SyndFeed feed = new SyndFeedImpl();
+ feed = ...
+ return feed;
+ }
+
+}
+
++------+
+
+ The servlet returns a feed upon HTTP GET requests with the <<>> method.
+
+
+ First the <<>> bean is obtained by invoking the <<>> method, the request object is passed as it could be used to obtain request contextual information to create the feed. How to create a feed using SyndFeed bean is explained in detail in the {{{./RssAndAtOMUtilitiEsROMEV0.5TutorialUsingROMEToCreateAndWriteASyndicationFeed.html}Using ROME to create and write a feed}} Tutorial.
+
+
+ Then the feed type of the response is determined, first looking at the request parameters and falling back to a default feed type (specified by a servlet init parameter) if the type is not indicated in the request parameters. Setting the feed type in the feed bean will indicate the <<>> the feed type to output.
+
+
+ Finally, the response is set with the proper content type (the MIME_TYPE constant is 'application/xml; charset\=UTF\-8') and the feed is written to response writer using the <<>> output classes.
+
+
+ Following is the full code for the servlet.
+
+
+
++------+
+
+package com.sun.syndication.samples.servlet;
+
+import com.sun.syndication.feed.synd.*;
+import com.sun.syndication.io.FeedException;
+import com.sun.syndication.io.SyndFeedOutput;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Sample Servlet that serves a feed created with ROME.
+ *
+ * The feed type is determined by the 'type' request parameter, if the parameter is missing it defaults
+ * to the 'default.feed.type' servlet init parameter, if the init parameter is missing it defaults to 'atom_0.3'
+ *
+ * @author Alejandro Abdelnur
+ *
+ */
+public class FeedServlet extends HttpServlet {
+ private static final String DEFAULT_FEED_TYPE = "default.feed.type";
+ private static final String FEED_TYPE = "type";
+ private static final String MIME_TYPE = "application/xml; charset=UTF-8";
+ private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed";
+
+ private static final DateFormat DATE_PARSER = new SimpleDateFormat("yyyy-MM-dd");
+
+ private String _defaultFeedType;
+
+ public void init() {
+ _defaultFeedType = getServletConfig().getInitParameter(DEFAULT_FEED_TYPE);
+ _defaultFeedType = (_defaultFeedType!=null) ? _defaultFeedType : "atom_0.3";
+ }
+
+ public void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
+ try {
+ SyndFeed feed = getFeed(req);
+
+ String feedType = req.getParameter(FEED_TYPE);
+ feedType = (feedType!=null) ? feedType : _defaultFeedType;
+ feed.setFeedType(feedType);
+
+ res.setContentType(MIME_TYPE);
+ SyndFeedOutput output = new SyndFeedOutput();
+ output.output(feed,res.getWriter());
+ }
+ catch (FeedException ex) {
+ String msg = COULD_NOT_GENERATE_FEED_ERROR;
+ log(msg,ex);
+ res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg);
+ }
+ }
+
+ protected SyndFeed getFeed(HttpServletRequest req) throws IOException,FeedException {
+ SyndFeed feed = new SyndFeedImpl();
+
+ feed.setTitle("Sample Feed (created with ROME)");
+ feed.setLink("http://rome.dev.java.net");
+ feed.setDescription("This feed has been created using ROME (Java syndication utilities");
+
+ List entries = new ArrayList();
+ SyndEntry entry;
+ SyndContent description;
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("ROME v0.1");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/rome01");
+ try {
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-08"));
+ }
+ catch (ParseException ex) {
+ // IT CANNOT HAPPEN WITH THIS SAMPLE
+ }
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Initial release of ROME");
+ entry.setDescription(description);
+ entries.add(entry);
+
+ entry = new SyndEntryImpl();
+ entry.setTitle("Rome v0.2");
+ entry.setLink("http://wiki.java.net/bin/view/Javawsxml/rome02");
+ try {
+ entry.setPublishedDate(DATE_PARSER.parse("2004-06-16"));
+ }
+ catch (ParseException ex) {
+ // IT CANNOT HAPPEN WITH THIS SAMPLE
+ }
+ description = new SyndContentImpl();
+ description.setType("text/plain");
+ description.setValue("Bug fixes, minor API changes and some new features"+
+ "