Re: [FreeMarker-user] Suggestion about the best BeansWrapper
Generates text that depends on changing data (like dynamic HTML).
Brought to you by:
revusky
From: Daniel D. <dd...@fr...> - 2012-05-15 06:45:02
|
Monday, May 14, 2012, 6:19:36 PM, Jacopo Cappellato wrote: [snip] > 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> Yeah, this is exactly the custom Map class issue I have mentioned regarding setSimpleMapWrapper(false). (Clearly, a new interface called TemplateMapModel should be added to FreeMarker that both supports non-string keys and separate method and variable namespaces, then TemplateHashModel should be deprecated.) > In order to fix these issues I have removed the method call: > defaultOfbizWrapper.setSimpleMapWrapper(true); > > In this way the screens seem to work fine. As far as you are using myMap.get(key) instead of myMap[key], or myMap[key] while the key doesn't accidentally clash with a method name... > 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? Since BeansWrapper.getDefaultInstance() returns an instance that is shared in the scope of the class-loader that defined the FreeMarker classes, and since possibly multiple independently developed components in your system use FreeMarker and thus getDefaultInstance (and you may don't even know about it), and since the returned BeanWrapper can be configured (not read-only), you never know how the returned BeanWrapper is configured. So you add a 3rd party component, and if you are unlucky, suddenly your other component is broken. As of creating new BeansWrapper, be sure you create it only once during the application life-cycle and then reuse the same instance, or else it will have to rebuild the class introspection cache again and again. (Ideally, the default instance would be non-configurable, so each component for which the default configuration is good could safely share it. But it's not how it is... It's again something that could be fixed in FreeMarker with a new ObjectWrapper class.) > Thank you > > Jacopo -- Best regards, Daniel Dekany |