2016-05-24 8 views
0

Я наблюдаю странное поведение с Freemarker. У меня есть Iterable в reportModel.affectedJars. Он предоставляется из базы данных графов - Tinkerpop/Titan.Freemarker - поведение встроенных в Iterables

${iterableHasContent(reportModel.affectedJars)?then("true", "false")}<br> 
${reportModel.affectedJars?has_content?then("yes", "no")} has_content<br> 
${reportModel.affectedJars?size}<br> 
${reportModel.affectedJars}<br> 
<#if reportModel.affectedJars?size == 0> 
    <p>No archives containing CVE vulnerabilities were found.</p> 
<#else> 
    <#list reportModel.affectedJars.iterator() as file> 
     Something... 

iterableHasContent является альтернативой ?size. я бы ожидать, что это будет вполне соответствовать, с точки зрения:

false 
no has_content 
0 
<p>No archives ... 

Но что на самом деле происходит это:

false 
yes has_content 
6 
--- and no iterations. --- 

который выглядит как есть какая-то глюк, что делает Freemarker думать, что Iterable не является пустой, но затем, когда он повторяется, он не дает никаких элементов. Никакое исключение не выбрасывается.

Я пытался отлаживать, но по какой-то причине отладчик не останавливается на соответствующем коде.

Есть что-то, что мне не хватает в ?size и ?has_content парадигмах, допускающих это поведение?

ответ

1

Не пытайтесь делать что-либо с этим Iterable, за исключением вызова iterator() на нем. Проблема в том, что FreeMarker был создан до того, как был введен Iterable, и он видит чистый Iterable (т. Е. Тот, который также не реализует Collection) как общий объект, а не какую-то перечислимую вещь. (Исправить это, не нарушая обратной совместимости, невозможно, хотя, конечно, для него должен быть вариант конфигурации.) Это также, где размер 6 исходит; это количество элементов в хеше, которое содержит его методы и свойства JavaBean. Ugh ...

Итак, после того, как вы получили Itera*tor*, следующая вещь вы найдете, что она не поддерживает ?size. Он поддерживает ?has_content. (Предполагается, что вы используете обертку объекта по умолчанию, а не чистую BeansWrapper, что является чистым злом.) Но если вы можете, используйте #list с вложенным #else. Что-то вроде:

<#list reportModel.affectedJars.iterator() as file> 
    Something... 
<#else> 
    <p>No archives containing CVE vulnerabilities were found.</p> 
</#list> 

или более реального примера жизни:

<#list reportModel.affectedJars.iterator()> 
    <p>Found some archives containing CVE vulnerabilities:</p> 
    <#items as file> 
     Something... 
    </#items> 
<#else> 
    <p>No archives containing CVE vulnerabilities were found.</p> 
</#list> 
+0

Спасибо за расширенную информацию! Я понял, что после некоторой отладки. Любые планы для некоторых Freemarker для Java 8? Или, возможно, поместите биты, которые нарушат совместимость Java 1.4 с каким-то плагином? –

+0

Проблема обратной совместимости не связана с версией Java (а с версии 2.3.24 для FreeMarker требуется Java 1.5). Речь идет о поведении существующих шаблонов. Что вы подразумеваете под FreeMarker для Java 8? Возможно, поддержка «Необязательно»? – ddekany

+0

При поддержке более ранних версий Java я имею в виду, главным образом, то, что может быть использовано <#list>, размером (если применимо), has_content и т. Д. Например, потоки Java 8. –