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/