Re: Preserving ordering in a Freemarker sequence when iterating over an OrderedBidiMap.

Stephen Smith <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Hi Jonathan,

Thanks for your explanation. Your answer makes a lot of sense, but as we using Freemarker in conjunction with Spring we 
can't access a Freemarker ObjectWrapper directly without exposing it in the Spring application context, which seems like 
a bit of a smell. So, our current workaround is to put our OrderedBidiMap inside a LinkedHashMap before sending it to 
the Freemarker ViewResolver.

I haven't had a chance yet to poke around inside the Freemarker codebase, but I'm a little hazy on why Freemarker knows 
about java.util.Map implementations specifically within java.util.*, but not other packages. Is Freemarker explicitly 
checking map implementation type for performance reasons?

Thanks

Steve.

---
Stephen Smith, MEng (Wales).
http://www.stephen-smith.co.uk/

Jonathan Revusky wrote:
> Stephen Smith wrote:
>> Hi,
>>
>> We're using an OrderedBidiMap from Commons Collections 3.x to store a 
>> mapping of
>> keys<->values (the implementation we use is TreeBidiMap). Our 
>> Freemarker syntax
>> is as follows:
>>
>>     <#list subjectsMap?keys as subjectName>
>>       ${subjectName}
>>     </#if>
>>
>> The problem is that the sequence is returning an unordered list of 
>> keys. The same
>> Freemarker syntax seems to work with a LinkedHashMap, but I don't 
>> understand what
>> Freemarker is doing under the hood when getting the map's keys. Surely 
>> it is just
>> calling Map#keySet, in which case our ordering should be preserved?
> 
> I think the problem is that the DefaultObjectWrapper is copying the map, 
> and by default, is using HashMap. The code in there is aware, for 
> example, of things in java.util.* such as LinkedHashMap or TreeMap and 
> will preserve order, but the default behavior with maps otherwise is to 
> copy them into a HashMap.
> 
> Perhaps you need to explicitly use the BeansWrapper. Just use:
> 
> BeansWrapper bw = new BeansWrapper();
> dataModel.put("subjectsMap", bw.wrap(subjectsMap));
> 
> Or, you could just set it as the default wrapper, and that would be 
> something like:
> 
> freeMarkerConfig.setObjectWrapper(new BeansWrapper());
> 
> 
>>
>> Is this a defect in Freemarker, 
> 
> Arguably, it is, though the whole issue is a bit complex...
> 
>> are we misusing the sequence syntax, or should we
>> pass through the OrderedBidiMap's entry set and then call getKey and 
>> getValue on
>> each bean?
> 
> For the moment, the solution would be to explicitly use 
> freemarker.ext.beans.BeansWrapper.
> 
> JR
> 
>>
>> Thanks in advance
>>
>> Stephen Smith
>>
>> -------------------------------------------------------------------------
>> This SF.net email is sponsored by: Microsoft
>> Defy all challenges. Microsoft(R) Visual Studio 2008.
>> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
>> _______________________________________________
>> FreeMarker-user mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>>
> 
> 
> 

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
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.