Please do not change FMA. If you want to change the Mini-language
grammar, then make the change in Mini-language.
The schema and Wiki reference page will need to be updated.
Adrian Crum
Sandglass Software
www.sandglass-software.com
On 9/26/2014 8:02 AM, Jacopo Cappellato wrote:
Adrian,
I have to resurrect this old thread because a customer reported this issue
recently and I can confirm it is still outstanding.
In rev. 1627718 I have committed a unit test to prove the use case that I was
trying to explain the last time; just comment out the last assertion and it
will fail.
This can be fixed by the following code change:
Index:
framework/base/src/org/ofbiz/base/util/collections/FlexibleMapAccessor.java
===================================================================
--- framework/base/src/org/ofbiz/base/util/collections/FlexibleMapAccessor.java
(revision 1627543)
+++ framework/base/src/org/ofbiz/base/util/collections/FlexibleMapAccessor.java
(working copy)
@@ -206,7 +206,7 @@
private String getExpression(Map<String, ? extends Object> base) {
String expression = null;
if (this.fse != null) {
- expression =
FlexibleStringExpander.openBracket.concat(UelUtil.prepareExpression(this.fse.expandString(base)).concat(FlexibleStringExpander.closeBracket));
+ expression =
UelUtil.prepareExpression(this.fse.expandString(base));
} else {
expression = this.bracketedOriginal;
}
However, since you are the original contributor of the code I am patching, I
would like your review.
Thanks,
Jacopo
On May 15, 2012, at 12:46 PM, Adrian Crum <[email protected]>
wrote:
On 5/15/2012 11:41 AM, Jacopo Cappellato wrote:
HiAdrian,
I am still getting an error; I did some debugging and here are my findings:
On May 15, 2012, at 10:50 AM, Adrian Crum wrote:
On 5/15/2012 7:22 AM, Jacopo Cappellato wrote:
Thank you Adrian, much appreciated.
I have a question about one of the changes you have committed:
+ if (this.resultFma.containsNestedExpression()) {
^^^ If this result-name attribute contains a nested expression, like
"${result1}"
+ String expression = (String)
this.resultFma.get(methodContext.getEnvMap());
^^^ then evaluate the expression using the main context (expression = "result1")
This doesn't work as expected and "expression" is null.
If I have the following code:
<set field="total" value="10" type="BigDecimal"/>
<set field="result1" value="totalOrders"/>
<field-to-result field="total" result-name="${result1}"/>
I would expect that the above returns: expression == "totalOrders"
Is it correct assumption?
Yes, that it the way it should work.
The problem I think is in FMA.getExpression(...):
protected String getExpression(Map<String, ? extends Object> base) {
String expression = null;
if (this.fse != null) {
expression =
FlexibleStringExpander.openBracket.concat(UelUtil.prepareExpression(this.fse.expandString(base)).concat(FlexibleStringExpander.closeBracket));
} else {
expression = this.bracketedOriginal;
}
return expression;
}
and specifically in line:
expression =
FlexibleStringExpander.openBracket.concat(UelUtil.prepareExpression(this.fse.expandString(base)).concat(FlexibleStringExpander.closeBracket));
because this.fse.expandString(base) returns:
"${totalOrders}"
rather than "totalOrders"
That should not happen. I will look into it.
-Adrian
and then (I guess) the value is not found in the resultmap and the expression
comes as null.
Is it possible?
Jacopo
+ FlexibleMapAccessor<Object> resultFma =
FlexibleMapAccessor.getInstance(expression);
^^^ Create a new FMA for the nested expression
+ resultFma.put(methodContext.getResults(), fieldVal);
^^^ then evaluate the nested expression using the result Map.
-Adrian
+ }...
if I read it correctly, if a nested expression is detected then a new FMA is
created as a local variable and the result value is added to that instead of
adding it to the instance FMA. Aren't we loosing the result in this way?
Thanks,
Jacopo
On May 14, 2012, at 10:50 PM, Adrian Crum wrote:
Jacopo,
I committed a fix in rev 1338394. Let me know if that solves your problem.
-Adrian
On 5/14/2012 1:54 PM, Adrian Crum wrote:
Then that seems to be a flaw in the<field-to-result> logic. I will look into
it.
-Adrian
On 5/14/2012 1:51 PM, Jacopo Cappellato wrote:
Ok, I am debugging it and the problem is actually in the method
FlexibleMapAccessor.put at line:
UelUtil.setValue(base, getExpression(base), value == null ? Object.class :
value.getClass(), value);
The problem is that the "base" map is the map containing the results and not the
"context" of the method.
For example:
<set field="total" value="10" type="BigDecimal"/>
<set field="result1" value="totalOrders"/>
<field-to-result field="total" result-name="${result1}"/>
This should add to the output the entry: ["totalOrders": 10]
It instead throws the error because the ${result1} is expanded using the "result" map rather than
the "context" map where the "result1" field is set.
Jacopo
On May 14, 2012, at 12:34 PM, Adrian Crum wrote:
It must be an old bug. As far as I know, the expression parsing hasn't changed
recently (with the exception of the recent security fix).
-Adrian
On 5/14/2012 11:27 AM, Jacopo Cappellato wrote:
Ok, I will try to look at it and find a fix... do you have any idea about why
the content of the brackets is removed during parsing? Is it related to recent
changes or it is an old bug? They may be silly questions but I actually don't
know much about this code.
Jacopo
On May 14, 2012, at 12:03 PM, Adrian Crum wrote:
That is a nested expression: The result name is contained in the variable named
"key".
UEL does not support nested expressions, but we make it work in
FlexibleStringExpander by pre-parsing the String and extracting nested
expressions.
In addition, FlexibleMapAccessor contains some code to handle nested
expressions (line 66 and 192). So, maybe that code can be improved to be
smarter.
-Adrian
On 5/14/2012 10:37 AM, Jacopo Cappellato wrote:
Hi Adrian,
we have noticed that the following instruction:
<field-to-result field="val" result-name="${key}"/>
(from ContentServices.xml) returns an error in the console:
2012-05-14 14:12:02,679 (default-invoker-Thread-11) [FlexibleMapAccessor.java:163:ERROR] UEL exception
while setting value: javax.el.ELException: Error parsing '${}': syntax error at position 2, encountered
'}',
expected<IDENTIFIER>|<STRING>|<FLOAT>|<INTEGER>|'true'|'false'|'null'|'-'|'!'|'not'|'empty'|'(',
original = ${key}
However it seems that the value is still returned properly. Any idea of how we
could fix it?
Thanks,
Jacopo