commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <si...@ecnetwork.co.nz>
Subject Re: [digester] rule that constructs a non-bean from parameters
Date Wed, 10 Mar 2004 23:58:22 GMT
On Thu, 2004-03-11 at 12:02, robert burrell donkin wrote:
> it's really a way to provide better support for immutable objects 
> (which Dimension is not. Doh!)
> 
> On 10 Mar 2004, at 22:52, robert burrell donkin wrote:
> 
> > i'm thinking of adding a rule that constructs a non-bean (in other 
> > words, a type without an empty constructor) from the parameters 
> > currently on the stack. i think that this would enable easier digester 
> > of type such java.awt.Dimension which may commonly be mapped to xml 
> > thus:
> >
> > 	<dimension>
> > 		<x>1.0</x>	
> > 		<y>1.2</y>
> > 	</dimension>

I agree that some mechanism for doing this would be very useful.

I can't see any way to support both this feature (creation via
non-default constructor) PLUS being able to make arbitrary calls to
methods on the constructed object via CallMethodRule/SetNextRule.

In other words, the object can't be created and then mutated. It can
either be created via ObjectCreatRule/FactoryCreateRule at element
start, then mutated, or created at element end - but not both.

As you say, all immutable objects qualify. Even objects which are not
immutable will work fine, as long as the user doesn't expect the
Digester to mutate them :-). So Dimension would be fine too.

I think that even with this limitation, such a rule would be an
excellent tool to add. 

One major issue though: the way that rules fire in reverse order at end
regularly catches users out (see Diego's email of today in the
commons-user list).

Given:
 digester.addCreateComplexObject("foo/bar", "java.awt.Point", 2);
 digester.addConstructorParam("foo/bar/x", 0);
 digester.addConstructorParam("foo/bar/y", 1);
 digester.addSetNext("foo/bar", "addPoint");

this will fail badly, because the SetNextRule's end method will fire
before the AddCreateComplexObject's end method, ie before the object is
created.

Of course the same currently happens with this:
  digester.addObjectCreate("foo/bar", "StringBuffer);
  digester.addCallMethodRule("foo/bar", "append", 0);
  digester.addSetNext("foo/bar", "addStrBuf");

The SetNextRule fires before the CallMethodRule, so the object passed to
the addStrBuf object is not (yet) initialized. However the impact is far
less critical; at least the StringBuffer object *exists*, and the target
of the addSetNext doesn't *normally* care that the target isn't
initialized. 

Users will *really* care if the SetNextRule tries to pass the "parent"
object to the "grandparent" object, which is what I believe will havven
with the addCreateComplexObject example above.

Of course all the above code is untested...I hope I'm right that this
problem actually exists as described above :-)

Emmanuel Bourg raised a proposal for having CallMethodRule fire as soon
as all of its params are available; we had a discussion on this list
just a week or so ago ["CallMethodRule order, bug 12997"]. The proposal
was rejected due to backward-compatibility issues, but would have
avoided this. As this is a new Rule, I guess we could instead take that
approach. It would make the new rule inconsistent with CallMethodRule
behaviour, though.


NB: I'll be away next week on holiday, so please don't think I'm not
interested if I don't respond to emails.

Regards,

Simon


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


Mime
View raw message