Hi all guys,
during the weekend, taking inspiration from a builder idea proposed by
James Carman[1] time ago, I spent some spare time on doing a local
experiment (complete at 75% with running tests copied and adapted from
trunk) on my beloved component, at the end of wich I realized it would
be a good time to propose a 3.0 version of Digester APIs and offer to
our users a new Digester experience, with new, fresh, *simplified*
APIs.

Existing Digester is mature and stable enough, but what I found points
of improvement are:
 * configuration APIs, I propose a unique point of configuration - at
this stage, users can configure the Digester instance by
    * the Digester itself;
    * the Rules;
    * the RuleSet;
    * the Loader;
 * too many loaders: one loader is enough, what it can do is loading
different digester modules/extensions;
 * there are configurations tasks that can be delegated to a Loader
instead of the Digester, such
    * SAX Parser settings;
    * ClassLoader settings;
    * ...
 * the Digester contains some features that IMHO can be dropped:
    * the StackAction listener - I wonder who used that in production;
    * the custom ContentHandler - it intercepts the default Digester
behavior that makes the Digester use == default SAX APIs

Being a Google-Guice user (I've been integrating it with many
frameworks such apache bval and mybatis on top, and I like how they
designed the Injector modularization) I took inspiration also from
their APIs so that's an overview of my proposal:

 * Users can configure digester rules by implementing RulesModule interface:

+-----------------------------------------------------------------------------+
class MyRuleModule implements RulesModule {

    public void configure(RulesBinder rulesBinder) {
        rulesBinder.when("employee")
            .objectCreate(Employee.class)
            .setProperties();
        rulesBinder.when("employee/address")
            .objectCreate("org.apache.commons.digester3.Address")
            .setProperties()
            .setNext("addAddress");
    }

}
+-----------------------------------------------------------------------------+

or, according to DRY principles, extending a provided AbstractRulesModules

+-----------------------------------------------------------------------------+
class MyRuleModule extends AbstractRulesModules {

    @Override
    public void configure() {
        when("employee")
            .objectCreate(Employee.class)
            .setProperties();
        when("employee/address")
            .objectCreate("org.apache.commons.digester3.Address")
            .setProperties()
            .setNext("addAddress");
    }

}
+-----------------------------------------------------------------------------+

 * users can obtain a Digester instances - Digester is not thread
safety so for each parsing operation a new one has to be created! -
using a DigesterLoader (methods can be chained using a Builder APIs)

+-----------------------------------------------------------------------------+
DigesterLoader loader = DigesterLoader.newLoader(new MyRuleModule())

.setNamespaceAware(true)

.setClassLoader(myClassLoader);
...
Digester digester = loader.newDigester();

    OR

digester = loader.newDigester(SAXParser mySaxParser);

    OR

digester = loader.newDigester(XMLReader myXMLReader);
+-----------------------------------------------------------------------------+

then parse documents

+-----------------------------------------------------------------------------+
Object myObject = digester.parse(new URL("http://my-rest.server/service.xml";));
+-----------------------------------------------------------------------------+

 * Users can still load rules from XML using provided modules:

+-----------------------------------------------------------------------------+
DigesterLoader loader = DigesterLoader.newLoader(new MyRuleModule(),
new org.apache.commons.digester3.xmlrules.FromXMLRulesModule(new
URL("http://my.host/my-shared-config.xml";)))

.setNamespaceAware(true)

.setClassLoader(myClassLoader);
+-----------------------------------------------------------------------------+

or from Annotations

+-----------------------------------------------------------------------------+
DigesterLoader loader = DigesterLoader.newLoader(new MyRuleModule(),
new 
org.apache.commons.digester3.annotations.FromAnnotationsRulesModule(Employee.class))

.setNamespaceAware(true)

.setClassLoader(myClassLoader);
+-----------------------------------------------------------------------------+

So now to show you the potential of new APIs, I would like to start
committing the stuff I realized locally - before they will be lost! :P
- but I don't know how would be the better way to start. Which one
fits better, a 3.X branch or the sandbox?
I'm open to your feedbacks, thoughts, suggestions, constructive
criticism. I estimated to complete this work in 2-3 weeks,
documentation included, depending on requested effort by my main job.
I'm confident on your help, please let me know!!!
All the best, have a nice day,
Simo

[1] https://issues.apache.org/jira/browse/DIGESTER-135


http://people.apache.org/~simonetripodi/
http://www.99soft.org/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to