You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@abdera.apache.org by James M Snell <ja...@gmail.com> on 2006/06/20 22:43:53 UTC

Subclassing and Alternatives

One of the things I've been wanting to enable for a while is the ability
for a developer to configure alternate implementations/subclasses of the
FOM* classes without requiring a complete new parser implementation to
be provided.  At the same time, I wanted to make it drop dead simple to
do so. Here's what I've come up with and have ready to check in if there
are no objections.

The Factory interface would expose a new method:

  <T extends Base>void registerAlternative(
    Class<T> base,
    Class<? extends T> alternative);

Looking past the generics for a second, this performs one very simple
task... whenever an object of type base is requested, the registered
alternative is created.  The alternative MUST extend the base and MUST
have identical constructors.

Together with some other changes to the model api's, this allows us to
do something like the following:

  class MyEntry extends FOMEntry { ... }

  Factory.INSTANCE.registerAlternative(FOMEntry.class, MyEntry.class);
  MyEntry entry = Factory.INSTANCE.newEntry();

  // or

  Document<Feed> doc = Parser.INSTANCE.parse(in);
  List<MyEntry> entries = feed.getRoot().getEntries();
  for (MyEntry myEntry : entries) {
    myEntry.myEntendedMethod(...);
  }

It is also possible to create a subclass of FOMFactory that registers
the alternates in the constructor.  That new Factory could then be new'd
up explicitly, or configured as the default for Factory.INSTANCE, thus
allowing an implementation to provide it's own extensions to the core
Model and FOM objects.  In certain setups, configuration of the
alternatives would be as simple as dropping a new Jar into the classpath.

  class MyFactory extends FOMFactory {
    public MyFactory() {
      registerAlternative(FOMEntry.class, MyEntry.class);
      ...
    }
  }

  ParserOptions options = Parser.INSTANCE.getDefaultParserOptions();
  options.setFactory(new MyFactory());

  Document<Feed> doc = Parser.INSTANCE.parse(in);
  List<MyEntry> entries = feed.getRoot().getEntries();
  for (MyEntry myEntry : entries) {
    myEntry.myEntendedMethod(...);
  }

Thoughts? Concerns?

- James