You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Mihai C." <co...@videotron.ca> on 2004/12/05 19:30:59 UTC

digester newbie question

Hi all, being new to digester, I have no clue how to get around my problem. 
Here's the story:
I'm trying to parse a config xml that looks like this:
<root>
     <a>
     .......
          <b>
          .....
          </b>
          <b>
          .....
          </b>
     </a>
     <a>
     .......
          <b>
          .....
          </b>
          <b>
          .....
          </b>
     </a>
</root>

I have two beans (ABean and BBean)
and the factory :
class Factory {
 processA(ABean ab){
  .......
 }
 processB(BBean bb){
  ........
 }
 digest(){
      Digester d = new Digester();
      d.push(this); //stack bottom
      d.addSetNext(      "root/a/b",   "processB" , "BBean"); // when 
root/a/b pattern mathes, execute processB on 'this' with BBean type param
      d.addSetNext(      "root/a",   "processA", "ABean"); // when root/a 
pattern mathes, execute processA on 'this' with ABean type param
      d.addObjectCreate( "root/a",   ABean.class);
      d.addObjectCreate( "root/a/b", BBean.class);

      ............... //var addCallMethod()
 }
}

I get this error:

[DEBUG] Digester - -[SetNextRule]{root/a/b} Call 
Factory.processB(ABean@fe64b9)
[ERROR] Digester - -End event threw exception 
<java.lang.IllegalArgumentException: argument type 
mismatch>java.lang.IllegalArgumentException: argument type mismatch

Obviously, processB() was called with the wrong arg type(ABean instead of 
BBean) and that because the BBean obj was just poped from the stack.

Can you please help?

-- mihai 



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


Re: digester newbie question

Posted by "Mihai C." <co...@videotron.ca>.
Thanks Simon and Matthijs for your detailed replies and the next questions 
will go user list with [digester] in head of subject :).
Finnaly addSetRoot allowed me to addObject imediatelly after pushing the 
Factory instance on stack.
What happens now is that when </b> is reached, the stack is poped (top BBean 
obj) and after, the processB is called with whatever is on top of stack 
(ABean). And here I get the error.
I must implement some mechanism to keep a copy of the top BBean past the 
</b> tag.

Anyway, I now I think I understood the problem, which counts as 90% of the 
sollution.

Thanks again,

--mihai

----- Original Message ----- 
From: "simon" <s_...@paradise.net.nz>
To: "Jakarta Commons Developers List" <co...@jakarta.apache.org>
Sent: Monday, December 06, 2004 5:07 PM
Subject: Re: digester newbie question


> On Mon, 2004-12-06 at 23:36, simon wrote:
>> >       Digester d = new Digester();
>> >       d.push(this); //stack bottom
>> >       d.addSetNext(      "root/a/b",   "processB" , "BBean"); // when
>> > root/a/b pattern mathes, execute processB on 'this' with BBean type 
>> > param
>> >       d.addSetNext(      "root/a",   "processA", "ABean"); // when 
>> > root/a
>> > pattern mathes, execute processA on 'this' with ABean type param
>> >       d.addObjectCreate( "root/a",   ABean.class);
>> >       d.addObjectCreate( "root/a/b", BBean.class);
>> >
>> > I get this error:
>> >
>> > [DEBUG] Digester - -[SetNextRule]{root/a/b} Call
>> > Factory.processB(ABean@fe64b9)
>> > [ERROR] Digester - -End event threw exception
>> > <java.lang.IllegalArgumentException: argument type
>> > mismatch>java.lang.IllegalArgumentException: argument type mismatch
>> >
>>
>>
>>
>> > Obviously, processB() was called with the wrong arg type(ABean instead 
>> > of
>> > BBean) and that because the BBean obj was just poped from the stack.
>>
>> No, I think what is happening is that Digester is attempting to call a
>> method
>>    processB(BBean)
>> on an object of type ABean. The ABean class presumably doesn't have such
>> a method.
>
> On re-reading the exception trace, I see I didn't look carefully enough
> the first time.
>
> I still stand by my original comments, but the reason you are getting
> this message:
>> [DEBUG] Digester - -[SetNextRule]{root/a/b} Call
>> Factory.processB(ABean@fe64b9)
> is because you called d.addSetNext("root/a/b", ...) before you called
> d.addObjectCreate("root/a/b", ...). This means that when the <b> element
> is found, an attempt is made to call processB (passing the top object on
> the stack) before the BBean object has been created and pushed on the
> stack.
>
> If you ensure the rules creating the ABean and BBean objects are added
> before the rules that call processA/processB, then you will get a
> *different* problem (being the one I described in my earlier email) but
> I think this will at least be a step forward...
>
> You may find it useful to download the "source" distribution of
> digester-1.6 and look in the src/examples directory to see some simple
> examples of how to use the commons digester.
>
> And in future, please direct this sort of question to the "user" list
> rather than the developer list. Almost all jakarta developers are also
> watching the user list, so you lose nothing by asking on the correct
> list. In addition there are many experienced coders on the user list who
> could help, but are not subscribed to the dev list.
>
> Cheers,
>
> Simon
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
> 



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


Re: digester newbie question

Posted by simon <s_...@paradise.net.nz>.
On Mon, 2004-12-06 at 23:36, simon wrote:
> >       Digester d = new Digester();
> >       d.push(this); //stack bottom
> >       d.addSetNext(      "root/a/b",   "processB" , "BBean"); // when 
> > root/a/b pattern mathes, execute processB on 'this' with BBean type param
> >       d.addSetNext(      "root/a",   "processA", "ABean"); // when root/a 
> > pattern mathes, execute processA on 'this' with ABean type param
> >       d.addObjectCreate( "root/a",   ABean.class);
> >       d.addObjectCreate( "root/a/b", BBean.class);
> > 
> > I get this error:
> > 
> > [DEBUG] Digester - -[SetNextRule]{root/a/b} Call 
> > Factory.processB(ABean@fe64b9)
> > [ERROR] Digester - -End event threw exception 
> > <java.lang.IllegalArgumentException: argument type 
> > mismatch>java.lang.IllegalArgumentException: argument type mismatch
> > 
> 
> 
> 
> > Obviously, processB() was called with the wrong arg type(ABean instead of 
> > BBean) and that because the BBean obj was just poped from the stack.
> 
> No, I think what is happening is that Digester is attempting to call a
> method
>    processB(BBean)
> on an object of type ABean. The ABean class presumably doesn't have such
> a method.

On re-reading the exception trace, I see I didn't look carefully enough
the first time.

I still stand by my original comments, but the reason you are getting
this message:
> [DEBUG] Digester - -[SetNextRule]{root/a/b} Call 
> Factory.processB(ABean@fe64b9)
is because you called d.addSetNext("root/a/b", ...) before you called
d.addObjectCreate("root/a/b", ...). This means that when the <b> element
is found, an attempt is made to call processB (passing the top object on
the stack) before the BBean object has been created and pushed on the
stack.

If you ensure the rules creating the ABean and BBean objects are added
before the rules that call processA/processB, then you will get a
*different* problem (being the one I described in my earlier email) but
I think this will at least be a step forward...

You may find it useful to download the "source" distribution of
digester-1.6 and look in the src/examples directory to see some simple
examples of how to use the commons digester.

And in future, please direct this sort of question to the "user" list
rather than the developer list. Almost all jakarta developers are also
watching the user list, so you lose nothing by asking on the correct
list. In addition there are many experienced coders on the user list who
could help, but are not subscribed to the dev list.

Cheers,

Simon



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


Re: digester newbie question

Posted by Matthijs Wensveen <mr...@wanadoo.nl>.
simon wrote:

>On Mon, 2004-12-06 at 07:30, Mihai C. wrote:
>  
>
>>Hi all, being new to digester, I have no clue how to get around my problem. 
>>Here's the story:
>>I'm trying to parse a config xml that looks like this:
>><root>
>>     <a>
>>     .......
>>          <b>
>>          .....
>>          </b>
>>          <b>
>>          .....
>>          </b>
>>     </a>
>>     <a>
>>     .......
>>          <b>
>>          .....
>>          </b>
>>          <b>
>>          .....
>>          </b>
>>     </a>
>></root>
>>
>>I have two beans (ABean and BBean)
>>and the factory :
>>class Factory {
>> processA(ABean ab){
>>  .......
>> }
>> processB(BBean bb){
>>  ........
>> }
>> digest(){
>>      Digester d = new Digester();
>>      d.push(this); //stack bottom
>>      d.addSetNext(      "root/a/b",   "processB" , "BBean"); // when 
>>root/a/b pattern mathes, execute processB on 'this' with BBean type param
>>      d.addSetNext(      "root/a",   "processA", "ABean"); // when root/a 
>>pattern mathes, execute processA on 'this' with ABean type param
>>      d.addObjectCreate( "root/a",   ABean.class);
>>      d.addObjectCreate( "root/a/b", BBean.class);
>>
>>      ............... //var addCallMethod()
>> }
>>}
>>
>>I get this error:
>>
>>[DEBUG] Digester - -[SetNextRule]{root/a/b} Call 
>>Factory.processB(ABean@fe64b9)
>>[ERROR] Digester - -End event threw exception 
>><java.lang.IllegalArgumentException: argument type 
>>mismatch>java.lang.IllegalArgumentException: argument type mismatch
>>
>>    
>>
>
>
>
>  
>
>>Obviously, processB() was called with the wrong arg type(ABean instead of 
>>BBean) and that because the BBean obj was just poped from the stack.
>>    
>>
>
>No, I think what is happening is that Digester is attempting to call a
>method
>   processB(BBean)
>on an object of type ABean. The ABean class presumably doesn't have such
>a method.
>
>The structure of your input xml implies that BBeans are children of
>ABeans. But you appear to be trying to map this structure to a different
>representation where ABean and BBean objects are children of a Factory
>object. If you *really* want to do this, then I expect a way can be
>found, but I doubt this is really what you want to achieve...
>
>Remember that Digester has an object stack. You push an instance of
>Factory on the stack initially. Then when an <a> tag is encountered,
>your rules tell digester to create and push an ABean object onto the
>stack, and call ProcessA on the (top-1) object (the Factory) passing the
>top object (the ABean). All is ok so far. But then the <b> tag *within*
>the <a> tag is encountered, so your rules tell Digester to create a
>BBean object, push it on the stack, then call ProcessB on the (top-1)
>object on the stack - which is an ABean. Now I think this probably *is*
>what you want - the <b> tag is within the <a> tag, indicating that BBean
>objects are children of ABean objects. So surely a method on the ABean
>should be invoked to handle its children... 
>
>I hope this helps. If not, please provide a little more information on
>why you don't want to map the input xml in the obvious manner..
>
>Regards,
>
>Simon
>  
>
I agree with Simon that you probably don't want to do what you want to do.
But if you really want to, you can call addSetRoot(..) to do exactly 
what you describe.

Regards,
Matthijs.

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


Re: digester newbie question

Posted by simon <s_...@paradise.net.nz>.
On Mon, 2004-12-06 at 07:30, Mihai C. wrote:
> Hi all, being new to digester, I have no clue how to get around my problem. 
> Here's the story:
> I'm trying to parse a config xml that looks like this:
> <root>
>      <a>
>      .......
>           <b>
>           .....
>           </b>
>           <b>
>           .....
>           </b>
>      </a>
>      <a>
>      .......
>           <b>
>           .....
>           </b>
>           <b>
>           .....
>           </b>
>      </a>
> </root>
> 
> I have two beans (ABean and BBean)
> and the factory :
> class Factory {
>  processA(ABean ab){
>   .......
>  }
>  processB(BBean bb){
>   ........
>  }
>  digest(){
>       Digester d = new Digester();
>       d.push(this); //stack bottom
>       d.addSetNext(      "root/a/b",   "processB" , "BBean"); // when 
> root/a/b pattern mathes, execute processB on 'this' with BBean type param
>       d.addSetNext(      "root/a",   "processA", "ABean"); // when root/a 
> pattern mathes, execute processA on 'this' with ABean type param
>       d.addObjectCreate( "root/a",   ABean.class);
>       d.addObjectCreate( "root/a/b", BBean.class);
> 
>       ............... //var addCallMethod()
>  }
> }
> 
> I get this error:
> 
> [DEBUG] Digester - -[SetNextRule]{root/a/b} Call 
> Factory.processB(ABean@fe64b9)
> [ERROR] Digester - -End event threw exception 
> <java.lang.IllegalArgumentException: argument type 
> mismatch>java.lang.IllegalArgumentException: argument type mismatch
> 



> Obviously, processB() was called with the wrong arg type(ABean instead of 
> BBean) and that because the BBean obj was just poped from the stack.

No, I think what is happening is that Digester is attempting to call a
method
   processB(BBean)
on an object of type ABean. The ABean class presumably doesn't have such
a method.

The structure of your input xml implies that BBeans are children of
ABeans. But you appear to be trying to map this structure to a different
representation where ABean and BBean objects are children of a Factory
object. If you *really* want to do this, then I expect a way can be
found, but I doubt this is really what you want to achieve...

Remember that Digester has an object stack. You push an instance of
Factory on the stack initially. Then when an <a> tag is encountered,
your rules tell digester to create and push an ABean object onto the
stack, and call ProcessA on the (top-1) object (the Factory) passing the
top object (the ABean). All is ok so far. But then the <b> tag *within*
the <a> tag is encountered, so your rules tell Digester to create a
BBean object, push it on the stack, then call ProcessB on the (top-1)
object on the stack - which is an ABean. Now I think this probably *is*
what you want - the <b> tag is within the <a> tag, indicating that BBean
objects are children of ABean objects. So surely a method on the ABean
should be invoked to handle its children... 

I hope this helps. If not, please provide a little more information on
why you don't want to map the input xml in the obvious manner..

Regards,

Simon



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