##### Rome

- Overview
- How Rome Works
- Tutorials And Articles
- Releases
- ROME Development Proposals

##### Project Documentation

- Project Information
- Project Reports

## 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 `rome.properties` file.

The default plugins definition file is included in the ROME JAR file, `com/sun/syndication/rome.properties`, 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, `/rome.properties`. And appends the plugins definitions to the existing ones. Note that if there are several `/rome.properties` files in the different CLASSPATH entries all of them are processed. The order of processing depends on how the `ClassLoader` 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 `rome.properties`) 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 `com.sun.syndication.io.impl.PluginManager`. 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 `com.sun.syndication.io.impl.FeedParsers` class (subclass of the `PluginManager`). This plugin manager looks for the `WireFeedParser.classes` property in all the `rome.properties` files. The fully qualified names of the parser classes must be separated by whitespaces or commas. For example, the default `rome.properties` 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 `com.sun.syndication.io.WireFeedParser` interface. Parser instances must be thread safe. The return value of the `getType()` 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 `com.sun.syndication.io.impl.FeedGenerators` class (subclass of the `PluginManager`). This plugin manager looks for the `WireFeedGenerator.classes` property in all the `rome.properties` files. The fully qualified names of the generator classes must be separated by whitespaces or commas. For example, the default `rome.properties` 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 `com.sun.syndication.io.WireFeedGenerator` interface. Generator instances must be thread safe. The return value of the `getType()` 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 `com.sun.syndication.synd.impl.Converters` class (subclass of the `PluginManager`). This plugin manager looks for the `Converter.classes` property in all the `rome.properties` files. The fully qualified names of the converter classes must be separated by whitespaces or commas. For example, the default `rome.properties` 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 `com.sun.syndication.synd.Converter` interface. Converter instances must be thread safe. The return value of the `getType()` 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 `rome.properties` 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 `com.sun.syndication.io.impl.ModuleParsers` class (subclass of the `PluginManager`). This plugin manager looks for the `.feed.ModuleParser.classes` and the `.item.ModuleParser.classes` properties in all the `rome.properties` 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 `rome.properties` 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 `com.sun.syndication.io.ModuleParser` interface. ModuleParser instances must be thread safe. The return value of the `getNamesapceUri()` 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 `com.sun.syndication.io.impl.GeneratorParsers` class (subclass of the `PluginManager`). This plugin manager looks for the `.feed.ModuleGenerator.classes` and the `.item.ModuleGenerator.classes` properties in all the `rome.properties` 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 `rome.properties` 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 `com.sun.syndication.io.ModuleGenerator` interface. ModuleGenerator instances must be thread safe. The return value of the `getNamesapceUri()` 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 tutorial for implementing a custom module.