commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From robert burrell donkin <rdon...@apache.org>
Subject Re: [Betwixt] Extending BeanRuleSet
Date Tue, 12 Aug 2003 19:22:37 GMT
hi daniel

i'm a little ill at the moment so you'll have to forgive me if i'm a 
little slow today

On Tuesday, August 12, 2003, at 01:16 AM, Daniel Rall wrote:

> I'm looking for a way of using Digester's addRule(FactoryCreateRule)
> method [1] with Betwixt's BeanReader to extend the processing used to
> create an instance to "perform other setup processing" [2].  I want to
> retain the existing recursive XML -> JavaBean processing behavior of
> BeanReader, and set another instance field using some contextual
> information which isn't available from my XML.

ok, sounds reasonable.

> <scarab-issues>
>     <import-type>create-different-db</import-type>
>     <module>
>         ...
>     </module>
>     ...
> </scarab-issues>
>
> When beginning processing the <scarab-issues> element, I'd like to set
> the instance field.  Other than that, I'd like things to act like I'm
> using a vanilla BeanReader.  I've tried simply making an extra
> BeanReader.addRule() call (inheritted from its Digester superclass),
> but when I attempt to access children of <scarab-issues> when
> processing using my additional rule, they're null.

i trust that you're using CVS HEAD (the integration of digester and 
betwixt has been improved since the last release).

> Here's a brief
> synopsis of the code in question (or is that questionable code? ;)

>         ...
>         BeanReader reader = new BeanReader();
>         reader.setXMLIntrospector(createXMLIntrospector());
>         reader.registerBeanClass(ScarabIssues.class);
>         reader.addRule("scarab-issues",
>                        new FactoryCreateRule(new ScarabIssuesFactory()));
>         reader.setErrorHandler(this);
>         return reader;
>     }
>
>     /**
>      * An ObjectCreationFactory which sets the ImportErrors instance
>      * used by a ScarabIssues instance.
>      */
>     class ScarabIssuesFactory extends AbstractObjectCreationFactory
>     {
>         public Object createObject(Attributes attributes)
>         {
>             ScarabIssues si = new ScarabIssues();
>             si.importErrors = this.importErrors;
>             LOG.info("DLR: Called createObject(" + attributes + ')');
>             return si;
>         }
>     }
> }
>
>
> Spare a clue?

i think i understand your problem and can offer a possible solution. i'll 
also try to explain why the above doesn't work.

the first problem is that importErrors really is a field (as opposed to a 
property). at the moment, betwixt and digester only really deal with 
properties out of the box.

the second problem is that digester rules are additive. when the 
scarab-issues element is encountered, the betwixt rule will create an 
instance of ScarabIssues and push it onto the main digester stack and then 
the object create rule will create an instance of ScarabIssues and push it 
also onto the stack. the property setting rules work on the top element on 
the stack - the one created by the object create rule. betwixt will return 
the bean that it has created.

i've got a lot of half finished betwixt code sitting around here, some of 
which would provide an elegant solution to your problem. it would allow 
you to register a custom factory (with betwixt) to create ScarabIssues 
beans. unfortunately, it may be a while before that makes it into the 
betwixt codebase.

for the moment, i'd suggest replacing the object create rule with a custom 
Rule implementation something like:

SetFieldRule extends Rule {
	public void begin (java.lang.String namespace, java.lang,String name, 
org.sax.Attributes attributes){
		ScarabIssues issues = (ScarabIssues) getDigester().peek();
		issues.importErrors = this.importErrors;
	}
}

registered with the same matching path.

hope that helps.

- robert


Mime
View raw message