Suggestion about the best BeansWrapper

Jacopo Cappellato <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Hi all,

recently Daniel Dekany helped me in this list to fix a deadlock condition happening under special conditions when OFBiz (http://ofbiz.apache.org) screens were rendering Freemarker templates; during that interesting thread Daniel also mentioned that the way about the way we use BeansWrapper in OFBiz; here is the relevant part of the conversation:

=====================================================
QUESTION (me): Currently in OFBiz we are using the default object wrapper:

BeansWrapper defaultOfbizWrapper = BeansWrapper.getDefaultInstance();

do you think we should use a different one?

ANSWER (Daniel): I'm not sure. There are two problems with the current one:

- If you look at what map keys FreeMarker sees (`<#list k as
 someMap?keys>${k} </#list>`), it mixes the actual Map keys with the
 methods of the Map class. This I already find annoying enough to
 stay away. But it's also dangerous, because if you are unlucky and
 have key like "get", then someMap.get and someMap[myDynamicKey]
 where myDynamicKey happens to be "get" will return the get method
 instead of the map item. You can think further what if you have
 a custom Map class and you add methods to it. Using
 someMap.get("theKey") is robust however, but too verbose.

- It doesn't wrap W3C DOM nodes automatically in a way so that the
 user can use FreeMarker's XML processing facility. It also doesn't
 wrap Jython or Rhino JavaScript objects nicely.

What I like to use is:

  BeansWrapper wrapper = new BeansWrapper();
  wrapper.setSimpleMapWrapper(true);

This will not expose the methods of Map-s, only the keys of it. If you
want to get a map item that has a non-string key, you don't have
someMap.get(key) anymore, but you can use someMap(key) instead. If
it's a custom Map class with custom methods that you want to call from
the template, then you are out of luck, however. And in your case
these changes wouldn't be backward-compatible.

As of supporting W3C DOM nodes, Jython and such, it's very easy to
create a custom ObjectWrapper that does that. Just look at
DefaultObjectWrapper.

As of DefaultObjectWrapper, it's burdened with backward-compatibly,
and so wraps collections on an technically awkward way, plus it
doesn't provide any hacks for the non-String key problem. I don't see
a point of using that.

Anyway, the situation with Map-s and the "advertised" object wrappers
is something that had to be hammered out for ages. Sadly nobody has
found the time/incentive for it so far...
=====================================================

Based on Daniel's suggestions I have tried to replace:

BeansWrapper defaultOfbizWrapper = BeansWrapper.getDefaultInstance();

with

BeansWrapper defaultOfbizWrapper = new BeansWrapper();
defaultOfbizWrapper.setSimpleMapWrapper(true);

Unfortunately this change causes some errors in several screens because of ftl code snippets like:

1) ${currency.get("description",locale)}
2) <#assign roleType = quoteRole.getRelatedOne("RoleType")>

In the above examples "currency" and "quoteRole" are instances of GenericValue; this is a custom OFBiz class that implements Map<String, Object>

In order to fix these issues I have removed the method call:
defaultOfbizWrapper.setSimpleMapWrapper(true);

In this way the screens seem to work fine.

However I am not sure if there are side effects or if there are real advantages in using:
new BeansWrapper();

rather than:

BeansWrapper.getDefaultInstance();

Could you please provide some hints?

Thank you

Jacopo


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.