How to pass parameters containing quotes in the expression of a service task?

question
Tags: #<Tag:0x00007f64b8fc6858>

#1

Hi,
I designed a service task component taking several parameters in the following way:

<component id=“myComponent” extends=“ServiceTask”>
  <attribute id=“tasktype” value=“Service” visible=“false”/>
  <attribute id=“expression” value="#{myBackendservice.invoke(execution, ‘[[dataparameters]]’)}" category=“edoras” visible=“false” export=“true” constant=“true”/>
  <attribute id=“dataparameters” optional=“false” category=“edoras” export=“true”/>
</component>

The problem arises when dataparameters contains quote (for example as part of a ternary operation such as #{(root.otherVariable == ‘Yes’ ? ‘yes’ : ‘no’)}).
There is no problem during the modelling of the process, but the app cannot be saved, due to failure during the parsing of the model. I totally understand why value="#{myBackendservice.invoke(execution, ‘(root.otherVariable == ‘Yes’ ? ‘yes’ : ‘no’)’)}" is problematic (the opening quote of ‘Yes’ is evaluated as closing quote of '(root.otherVariable == '), and I would like to know if there is any change I can make either to my palette or to the process model to avoid this parsing error. Also, given that dataparameters may contain a pure string value, or even a map, removing the quotes in ‘[[dataparameters]]’ does not seem to be an option.

I tried without success escaping the quotes with backslashes inside dataparameters (in the end, the backslashes got themselves escaped, thus having no effect on the quotes), and using double-quotes instead of single quotes (it failed as well, although the error was different: it was about \" being an invalid escape sequence when \’ or \\ were expected).
I also tried to use &quot; instead of the single quotes, which allowed the model to be successfully saved, but the service task did not work as expected, as the service task received &quot; in the parameter value instead of the real quotes. Same situation when using %27, or &#39;.

For now, the only workaround is to not use my new component when the parameter contain an operation containing quotes, and to directly use a standard service task with custom expression in my model. Given other parameters of the service task, this is however a very fastidious work and cannot be a long-term solution.

Many thanks in advance for your help,
Tiffany

P.S.: quotes may appear weird in the pieces of code I wrote, but that’s mainly due to the stylesheet of this webpage :slight_smile:


#2

Hi Tiffany.

I did something similar with the plain process model. It means that I did not use modeler to convert model from its json representation in modeler into bpmn20.xml.
The xml representation which worked for me was:

<serviceTask id="valueExpressionServiceWithResultVariableNameSet"
             activiti:resultVariable="result"
             activiti:expression="#{bean.value == &quot;Yes&quot;}"/>

Regards
Martin


#3

Hi Martin,
Thank you for your quick reply and suggestion.
I have not tested your proposition because it requires to set the ternary operation directly in the palette expression, which defeats the points of having dataparameters (in our case, it is a Complex attribute)…
In the meantime, I kept investigating, however, and it seems that the problems comes from too many encoding (first as part of the HTTP request, which replaces &quote; with &amp;quote; but " with &quote;, and then escaping \ which becomes \\, so \' becomes \\').
I will be off for a whole week now, and will come back afterwards to try new things. It may be that the excessive encoding is due to the type of dataparameters(I will try to make it a SimpleText attribute when I am back from holidays.
Best,
Tiffany


#4

Hi @martin_grofcik
Thanks a lot for your support.
The reason why my input was replaced when encoded in the HTTP request was that I had written &quote; instead of &quot;. Damn “e”.
Although your proposition could work well, I also noticed that the best way to pass the string value to my service task (where the dataparameters is then deserialized as a JsonNode), and then run GearExpressionResolver on this the parameter values (which could be either a quoted string or a variable in my case) was to use \u0022.

I think the specificity of my issue is that dataparametersis of type Complexor RestComplex. Because otherwise it would obviously be possible to do:

<attribute id="expression" value="#{myBackendservice.invoke(execution, [[dataparameters]])}" type="SimpleText" category="edoras" visible="false" export="true" constant="true"/>
<attribute id="dataparameters" optional="false" value="root.otherVariable == 'Yes' ? 'yes' : 'no'" type="SimpleText" category="edoras" export="true"/>

However, in my case, I have to do:

<attribute id="expression" value="#{myBackendservice.invoke(execution, '[[dataparameters]]')}" type="SimpleText" category="edoras" visible="false" export="true" constant="true"/>
<attribute id="dataparameters" optional="false" value="" type="Complex" category="edoras" export="true">
    <complex-items>
        <complex-item id="key" name="Key" value="" width="100" optional="false"
                              type="SimpleText" />
        <complex-item id="value" name="Value" value="" width="250" optional="false"
                              type="SimpleText" />
    </complex-items>
</attribute>

and then put an item with value root.otherVariable == \u0022Yes\u0022 ? \u0022yes\u0022 : \u0022no\u0022. It’s definitely not the nicest, especially from a modelling point of view… but it works.

Best regards
Tiffany


EDIT:
As I said, given how unfriendly to modelers the above solution is, so I guess I’ll just do:

<attribute id="expression" value="#{myBackendservice.invoke(execution)}" type="SimpleText" category="edoras" visible="false" export="true" constant="true"/>

and extract the dataprameters from the execution in the backend service (even though I initially wanted to avoid having to hard-code the name “dataparameters” in my Java class…)


closed #5

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.