commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Kitching <skitch...@apache.org>
Subject Re: [digester] call-method-rule
Date Wed, 25 May 2005 23:40:53 GMT
On Wed, 2005-05-25 at 16:53 +0300, Markos Charatzas wrote:
> Hi again! :D
> 
> Knowing that "call-method-rule" and "call-param-rule" dont have a strong 
> association between them, Im facing a problem where although a 
> "call-method-rule" is specified, doesn't actually get called.
> 
> Using xml rules I have the following...
> -------------------------------------------------------
> <pattern value="routes/route/ship">    
> 	<object-create-rule classname="gr.forthnet.enosis.oli.pojos.OLIShip" />
> 	<bean-property-setter-rule pattern="code" />
> 	<call-method-rule pattern="name" methodname="setEnglishName" 
> paramcount="1" />		
> 	<call-param-rule paramnumber="0" pattern="name/english" />
> 	<call-method-rule pattern="name" methodname="setGreekName" paramcount="1" />	

> 	<call-param-rule paramnumber="0" pattern="name/greek" />		
> 	<set-next-rule methodname="setShip" />									
> </pattern>
> -------------------------------------------------------
> 
> I noticed that removing either of them, the remaining one works flawlessly...
> 
> Am I missing smth?

I think you've struck the design flaw in CallMethodRule.

CallMethodRule uses a single stack to store its parameters on. So when
you have two "interlaced" callmethodrules like this then the parameters
can get mixed up between the calls.

And there's an additional (documented) feature with CallMethodRule which
is that a call to a method with exactly one parameter doesn't fire if
the parameter is not available. This is meant to handle the case where a
class has a default value (for "englishName" for example) and you don't
want to override that by calling setEnglishName(null) when there is no
xml tag for the parameter.

So in your case, I bet that when both name/english are undefined, no
call gets made. But when both are defined, I suspect that the parameter
associated with one method gets set twice - first to the english name,
then overwritten with the greek name. And then that method gets called
because the parameter is non-null. But the other method sees its
parameter has never been set, and so skips the call.

Regarding a solution for your case: I think it is probably easiest for
you to just write custom rules for setting the english and greek names.

// note: rough code only

class SetGreekNameRule {
  public void body(elementNamespace, elementName, bodyText) {
    OLIShip ship = (OLIShip) digester.peek();
    ship.setGreekName(bodyText);
  }
}

digester.addRule(
  "routes/route/ship/name/greek", 
  new SetGreekNameRule());

// and same for the english name

Of course you're using that blasted xmlrules stuff so you'll need to
figure out how to access your custom rule classes. There is something
called "programmatically defined rules" that I think does the job.

Regards,

Simon


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


Mime
View raw message