You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Rob Cash <Ro...@nortelnetworks.com> on 2004/06/24 22:30:20 UTC

[Digester] Create an object using parent attribute

I'm trying to figure out how I can create an object using a parent attribute
value as the className for the child. Here's a sample XML snipet:

<parent childClass="mypackage.childClass">
   <child attribute1="value1" attribute2="value2"/>
   <child attribute1="value3" attribute2="value4"/>
</parent>

I've created and initialized parent with the following:

        digester.addObjectCreate("parent", "mypackage.parentClass");
        digester.addSetProperties("parent");

The problem comes in with creating the child. I've looked at archives of this
news group and haven't found the right way to do this with a current version.
I'm new to Digester and the documentation, while not bad, leaves something to be
desired. What I'd like to do is something like this:

        digester.addObjectCreate("parent/child", <value of
parent.getChildClass()>);

Do I need to create my own ObjectCreationFactory to do this?


Thanks in advance.

Cheers,
Rob
-- 
Rob Cash
Technical Architect & Application Developer
Information Services
Nortel Networks (http://www.nortelnetworks.com)
Tel: (919) 992-7871




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


Re: [Digester] Create an object using parent attribute

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Sat, 2004-06-26 at 03:51, Rob Cash wrote:
> "Bill Keese" <bi...@tech.beacon-it.co.jp> wrote in message
> news:40DB6DA1.9020205@tech.beacon-it.co.jp...
> >
> > >I'm trying to figure out how I can create an [child] object using a parent
> attribute
> > >value as the className for the child. Here's a sample XML snipet:
> > >
> > ><parent childClass="mypackage.childClass">
> > >   <child attribute1="value1" attribute2="value2"/>
> > >   <child attribute1="value3" attribute2="value4"/>
> > ></parent>
> > >
> > I thought that typically ObjectCreationFactory only looks at the
> > attributes of the element currently being processed, but I suppose you
> > could design one that looked at the value of the top element on the
> > stack. Alternately you could pipe your XML through XSLT to transform it
> > into something more digester-friendly.
> 
> Yeah, I supposed the alternative would be something like this:
> 
> <parent>
>    <child className="mypackage.childClass" attribute1="value1"
> attribute2="value2"/>
>    <child className="mypackage.childClass" attribute1="value3"
> attribute2="value4"/>
> </parent>
> 
> Then i could use the className attribute of the current object on the stack to
> create each child object. I would still have to create my own
> ObjectCreationFactory, though, to use the attribute className as the name of the
> class to use when instantiating the object, right? I didn't see a
> Digester.addObjectCreate() method that would work.

The latter syntax is certainly more "normal" for digester. If you use
this syntax then you can use the FactoryCreateRule with an
attribute-name:

Class defaultChildClass = StandardChild.class;
digester.addFactoryCreate(
	"parent/child", defaultChildClass, "className");

If your child objects require significant configuration data, then you
may also wish to check out the "plugins" module currently in CVS. It's
very stable (we're very close to a new release of Digester). If,
however, your child objects only need a couple of attributes, as per
your example, then using the "plugins" facility is probably "overkill".


Regards,

Simon


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


Re: [Digester] Create an object using parent attribute

Posted by Rob Cash <Ro...@nortelnetworks.com>.
"Bill Keese" <bi...@tech.beacon-it.co.jp> wrote in message
news:40DB6DA1.9020205@tech.beacon-it.co.jp...
>
> >I'm trying to figure out how I can create an [child] object using a parent
attribute
> >value as the className for the child. Here's a sample XML snipet:
> >
> ><parent childClass="mypackage.childClass">
> >   <child attribute1="value1" attribute2="value2"/>
> >   <child attribute1="value3" attribute2="value4"/>
> ></parent>
> >
> I thought that typically ObjectCreationFactory only looks at the
> attributes of the element currently being processed, but I suppose you
> could design one that looked at the value of the top element on the
> stack. Alternately you could pipe your XML through XSLT to transform it
> into something more digester-friendly.

Yeah, I supposed the alternative would be something like this:

<parent>
   <child className="mypackage.childClass" attribute1="value1"
attribute2="value2"/>
   <child className="mypackage.childClass" attribute1="value3"
attribute2="value4"/>
</parent>

Then i could use the className attribute of the current object on the stack to
create each child object. I would still have to create my own
ObjectCreationFactory, though, to use the attribute className as the name of the
class to use when instantiating the object, right? I didn't see a
Digester.addObjectCreate() method that would work.

Cheers,
Rob




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


Re: [Digester] Create an object using parent attribute

Posted by Bill Keese <bi...@tech.beacon-it.co.jp>.
>I'm trying to figure out how I can create an [child] object using a parent attribute
>value as the className for the child. Here's a sample XML snipet:
>
><parent childClass="mypackage.childClass">
>   <child attribute1="value1" attribute2="value2"/>
>   <child attribute1="value3" attribute2="value4"/>
></parent>
>
I thought that typically ObjectCreationFactory only looks at the
attributes of the element currently being processed, but I suppose you
could design one that looked at the value of the top element on the
stack. Alternately you could pipe your XML through XSLT to transform it
into something more digester-friendly.

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


Re: [Digester] Create an object using parent attribute

Posted by Rob Cash <Ro...@nortelnetworks.com>.
"Simon Kitching" <si...@ecnetwork.co.nz> wrote in message
news:1088123321.26657.37.camel@pcsimon...
[snip]
> How about this??
>
> public class ChildCreationFactory implements ObjectCreationFactory {
>   public Object createObject(Attributes x) {
>     ParentClass parent = (ParentClass) digester.peek();
>     String childClassName = parent.getChildClassName();
>
>     // create instance of child class and return it
>   }
> }
>
> digester.addObjectCreate("parent", ParentClass.class);
> digester.addSetProperties("parent");
> digester.addFactoryCreate("parent/child", new ChildCreationFactory());
> digester.addSetNext("parent/child");
>
>
> That looks much better...[I hope]
>

I think that this will do what I was looking for. Now to implement it...

Thanks for the pointers!

> Regards,
>
> Simon


Cheers,
Rob




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


Re: [Digester] Create an object using parent attribute

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Fri, 2004-06-25 at 12:55, Bill Keese wrote:
> >How about this??
> >
> >public class ChildCreationFactory implements ObjectCreationFactory {
> >  public Object createObject(Attributes x) {
> >    ParentClass parent = (ParentClass) digester.peek();
> >    String childClassName = parent.getChildClassName();
> >
> >    // create instance of child class and return it
> >  }
> >}
> >  
> >
> Looks good to me. I think that's what the original poster wanted. He
> just needs to add in the parts using reflection to instantiate the child
> object and set the attributes on it. Although, I guess the reflection
> code is a bit tricky, especially if there are type conversions, such as
> converting a string value of an attribute into a number. (Basically,
> it's re-implementing whatever digester.addSetProperties() does.)

Well, once the FactoryCreateRule has invoked the ChildCreationFactory to
create an instance of the right type and pushed it onto the digester
object stack, things look just like it was created via a "normal"
ObjectCreateRule, so I don't see any reason why a normal
SetPropertiesRule couldn't then be used:

  digester.addFactoryCreate("parent/child", new ChildCreationFactory());
  digester.addSetProperties("parent/child");

I don't believe the object creation factory needs to set the child
properties. Yes, the createObject method is *passed* the attributes, so
it *could* set them if it wanted to, but I don't think it is
necessary...

Regards,

Simon


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


Re: [Digester] Create an object using parent attribute

Posted by Bill Keese <bi...@tech.beacon-it.co.jp>.
>How about this??
>
>public class ChildCreationFactory implements ObjectCreationFactory {
>  public Object createObject(Attributes x) {
>    ParentClass parent = (ParentClass) digester.peek();
>    String childClassName = parent.getChildClassName();
>
>    // create instance of child class and return it
>  }
>}
>  
>
Looks good to me. I think that's what the original poster wanted. He
just needs to add in the parts using reflection to instantiate the child
object and set the attributes on it. Although, I guess the reflection
code is a bit tricky, especially if there are type conversions, such as
converting a string value of an attribute into a number. (Basically,
it's re-implementing whatever digester.addSetProperties() does.)

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


Re: [Digester] Create an object using parent attribute

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
On Fri, 2004-06-25 at 12:19, Bill Keese wrote:
> >><parent childClass="mypackage.childClass">
> >>   <child attribute1="value1" attribute2="value2"/>
> >>   <child attribute1="value3" attribute2="value4"/>
> >></parent>
> >>
> >>        digester.addObjectCreate("parent", "mypackage.parentClass");
> >>        digester.addSetProperties("parent");
> >>
> >>    
> >>
> Did I misunderstand the meaning of the original post? I thought the
> above example should create a mypackage.parentClass object which
> contains 2 mypackage.childClass objects. Right?

No, sorry, my mistake not yours. I completely misread the original post.
Thanks for pointing that out! [and please ignore my previos post].

How about this??

public class ChildCreationFactory implements ObjectCreationFactory {
  public Object createObject(Attributes x) {
    ParentClass parent = (ParentClass) digester.peek();
    String childClassName = parent.getChildClassName();

    // create instance of child class and return it
  }
}

digester.addObjectCreate("parent", ParentClass.class);
digester.addSetProperties("parent");
digester.addFactoryCreate("parent/child", new ChildCreationFactory());
digester.addSetNext("parent/child");


That looks much better...[I hope]

Regards,

Simon


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


Re: [Digester] Create an object using parent attribute

Posted by Bill Keese <bi...@tech.beacon-it.co.jp>.
>><parent childClass="mypackage.childClass">
>>   <child attribute1="value1" attribute2="value2"/>
>>   <child attribute1="value3" attribute2="value4"/>
>></parent>
>>
>>        digester.addObjectCreate("parent", "mypackage.parentClass");
>>        digester.addSetProperties("parent");
>>
>>    
>>
Did I misunderstand the meaning of the original post? I thought the
above example should create a mypackage.parentClass object which
contains 2 mypackage.childClass objects. Right?

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


Re: [Digester] Create an object using parent attribute

Posted by Simon Kitching <si...@ecnetwork.co.nz>.
Hi Rob,

On Fri, 2004-06-25 at 08:30, Rob Cash wrote:
> I'm trying to figure out how I can create an object using a parent attribute
> value as the className for the child. Here's a sample XML snipet:
> 
> <parent childClass="mypackage.childClass">
>    <child attribute1="value1" attribute2="value2"/>
>    <child attribute1="value3" attribute2="value4"/>
> </parent>
> 
> I've created and initialized parent with the following:
> 
>         digester.addObjectCreate("parent", "mypackage.parentClass");
>         digester.addSetProperties("parent");
> 
> The problem comes in with creating the child. I've looked at archives of this
> news group and haven't found the right way to do this with a current version.
> I'm new to Digester and the documentation, while not bad, leaves something to be
> desired. What I'd like to do is something like this:
> 
>         digester.addObjectCreate("parent/child", <value of
> parent.getChildClass()>);
> 
> Do I need to create my own ObjectCreationFactory to do this?
> 
What you are trying to achieve seems rather unusual to me. Each parent
instance created will have exactly one child object. Normally,
parent-child relations are 1:n rather than 1:1.

If this is a "side-effect" rather than your real final goal, then
perhaps you could describe what effect you are really trying to achieve.

Assuming that you have a good reason for building a 1:1 relationship
like this, you can probably achieve it by using a custom Rule class. The
problem with the xml you want to process is that you want one xml tag
(the <parent> tag) to create *two* objects simultaneously (the parent
and the child), and none of the existing rules handle this.

Creating a custom Rule instance is quite easy, and Digester is
explicitly designed to allow this. 


I think you can get the effect you describe above by doing the
following:

Copy the FactoryCreateRule class, and modify it for your purposes. It
will be simplest if you don't make any attempt to make the new rule
"generic"; hard-wire the parent class name, etc (at least for the first
implementation).

When begin() is called, the new rule should:
* create an instance of ParentClass and push it on the digester stack
* get the value of the "childClass" attribute
* create an instance of the child class
* call some method on the parent class instance to tell it
  about the child class [I presume you want this]
* push the child instance on the digester stack

When end() is called, the new rule should:
* pop 2 objects off the digester stack (the child then the parent)


Regards,

Simon


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