commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rahul Akolkar <rahul.akol...@gmail.com>
Subject Re: [scxml] datamodel, custom actions and digester
Date Wed, 11 Aug 2010 21:04:41 GMT
On Wed, Aug 11, 2010 at 3:51 PM, Abigail Gertner <gertner@mitre.org> wrote:
>
>
> On 8/11/2010 3:36 PM, Rahul Akolkar wrote:
>> On Wed, Aug 11, 2010 at 2:19 PM, Abigail Gertner <gertner@mitre.org> wrote:
>>
>>>
>>> On 8/11/2010 12:29 AM, Rahul Akolkar wrote:
>>>
>>>> <snip/>
>>>> The way to obtain the live values of the datamodel is to use the
>>>> expression evaluator, see interfaces mentioned here:
>>>>
>>>>   http://commons.apache.org/scxml/guide/contexts-evaluators.html
>>>>
>>>>
>>>>
>>> Is it possible to call a method using the expression evaluator with an
>>> argument that is a node in the XML tree, rather than just a string value?
>>>
>>>
>> <snip/>
>>
>> Executable content is open ended in SCXML, as largely speaking most
>> things are possible with custom actions. I'm afraid I've lost the
>> bigger picture of your scenario in the pin-pointed question above.
>>
>> To obtain a node using the expression evaluator, use
>> Evaluator#evalLocation(...) which returns a Node.
>>
>
> What I mean is, if I want to do something like:
>
> <onentry>
>  <cs:var name="result" expr="foo.bar(...)"/>
> </onentry>
>
> Where the argument to foo.bar() is a Node from the datamodel, but with
> the current context values included, how can I get that from the
> expression evaluator. I tried using the Data('var','path') expression
> but it doesn't seem to work for nodes.
>
<snip/>

Here are some ways to tackle this:

 * Break the above into smaller operations: (1) obtain a node, (2)
invoke the method. For example:

    <onentry>
      <my:node name="arg" expr="..."/>
      <cs:var name="result" expr="foo.bar(arg)"/>
    </onentry>

  where <my:node> uses Evaluator#evalLocation(...) and creates a "var"
matching the name argument.

 * Use XPath as the expression language as its better equipped to deal
with XML nodes. The above would then become:

   <onentry>
     <cs:var name="result" expr="foo:bar($dataid/xpath/to/node)"/>
   </onentry>

   However, the XPath evaluator isn't available in the latest release
however, but rather in a branch:

   http://svn.apache.org/repos/asf/commons/proper/scxml/branches/J6/src/main/java/org/apache/commons/scxml/env/xpath/

 * A bit of background - The Data() function is mostly limited to
values of leaf nodes (strings, integers) and is designed to satisfy
the rvalue of most assignment expressions. There is a corresponding
LData() -- I presume you're using JEXL -- that is meant to satisfy the
lvalue (and will return nodes) but these are implementation details so
resorting to using LData isn't recommended.


>>>> Might be worthwhile revisiting the need for using
>>>> SCXMLParser#newInstance() rather than the static parse methods.
>>>>
>>>>
>>>>
>>>>
>>> The reason I am doing this is that I am using xinclude to include a
>>> separate xml file and I found that I needed to call setXIncludeAware()
>>> on the parser to make it do the include. Is there some way to do this
>>> using the static parse methods?
>>>
>>>
>> <snap/>
>>
>> Not in the latest release (v0.9) so thats one of the cases where you
>> may indeed not be able to use the static parse methods. Based on what
>> I've read so far, it seems your best bet may be to register the
>> digester rules for your custom actions by hand after you obtain the
>> new instance and let the custom action do the appropriate expression
>> evaluation and datamodel / context processing.
>>
> I'm trying to do it this way now and having trouble getting the custom
> action to fire. I am using
>
> dig.addObjectCreate("!*/onentry/sendMessage", SendMessage.class);
>
> Where my custom action is called SendMessage.
>
> Then in my scxml file I have
>
> <onentry>
>  <sendMessage/>
> </onentry>
>
> The SendMessage object is being created when the file is parsed, but the
> execute() method is not being called when the state is entered.
> Do I have to do something else to get it to call execute()?
>
<snap/>

Minimally, you'll have to add the SetNextRule (and maybe others, as
per your action needs), so this:

  dig.addSetNext("!*/onentry/sendMessage", "addAction");

Also, best to use a different XML namespace for custom actions. See
Digester#setRuleNamespaceURI(...) for this purpose.

-Rahul

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


Mime
View raw message