commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <>
Subject Re: [digester] help with multi-argument constructor
Date Mon, 26 May 2003 05:09:08 GMT
On Sat, 2003-05-24 at 13:30, Christopher Bare wrote:
> Hi,
> I'm trying to parse XML something like this:
>   <user>
>     <id>1</id>
>     <name>chris</name>
>   </user>
> As a result, I would like the following constructor to
> be called:
>    public User( long id, String username )
>    {
>       //...
>    }
> I read in the javadocs that "FactoryCreateRule" is
> used to create instances of classes without a
> no-argument constructor, but, as far as I can tell, an
> ObjectCreationFactory is set up to use attributes, and
> not enclosed elements, for constructor parameters.
> Please correct me if I'm wrong here.

I think you're correct here. The factory only works with attributes.

> Otherwise, is there a way to do this? Sorry if I'm
> missing something totally obvious, and thanks for any
> insight.
> I know... I could just add "set" methods and an empty
> constructor, but I hate to expose public "set" methods
> for the world to use and abuse where it's not really
> appropriate.
> If there's not already an obvious way to do this, and
> I'm just clueless, I think something like the
> following would be cool:
>    digester.addCallConstructor( "users/user",
> User.class, 2 );
>    digester.addCallParam( "users/user/id", 0 );
>    digester.addCallParam( "users/user/name", 1 );

The problem with what you are suggesting here is that the object you are
constructing will not be created until the end tag is encountered,
because all the subtags need to be seen first in order to gather the
required parameters (the Digester is based on SAX, not DOM).

Remember that the digester's central concept is a stack of objects. The
ObjectCreateRule and FactoryCreateRule both ensure that the object is
created as soon as the *start* tag for the element is processed. The
created object then resides on the object stack until the end tag is
encountered, allowing other rules which operate upon the top object of
the stack to refer to the instance.

Because what you are suggesting requires delaying the construction of
the target object until the *end* tag for the element is processed, this
results in the constructed object spending zero time upon the object
stack, making it impossible for other rules to ever reference it.

In particular, I expect that you will want to apply the "setNext" rule
in order to tell some parent object that your new "user" object exists.
This simply isn't possible with the proposed solution.

I assume you have some object representing a "set of users", which is
created by an ObjectCreateRule when the <users> tag is encountered. You
could therefore place a factory method on that class, and do:

digester.addCallMethod("users/user", "createUser", 2);
digester.addCallParam("users/user/id", 0);
digester.addCallParam("users/user/name", 1);

Still, it would be nice to be able to construct an object with
parameters based upon nested tags. Anyone else out there got any



View raw message