Получите список всех имен зависимостей(даже многоуровневого наследования) из строки шаблона в FreeMarker

#java #templates #freemarker #template-engine

Вопрос:

Я пытался использовать механизм шаблонов FreeMarker в личном проекте maven.

Я хотел спросить, есть ли у FreeMarker открытый метод, который, учитывая тело шаблона в виде строки, может возвращать список всех имен шаблонов зависимостей (которые используют директивы #import и #include).

Если да, то не могли бы вы, пожалуйста, указать мне правильную часть кодовой базы, связанную с этим? Даже если такого публичного метода нет, не могли бы вы указать мне, пожалуйста, на частный метод, который выполняет это?

Я не уверен, есть ли способ каким-либо образом изменить имя директивы во FreeMarker(например, псевдонимы в bash? Или объявления «using» в C , или, возможно, любая директива, определенная пользователем в FreeMarker). Если есть, то при написании такого простого синтаксического анализатора могут возникнуть ошибки, потому что, если он не найдет <#import> или <#include> директив, мы не получим имен шаблонов зависимостей, таких как псевдоним или директива, определенная пользователем.

Итак, есть ли какие-то такие вещи, на которые мне нужно обратить особое внимание? Или я могу написать простой синтаксический анализатор собственного использования String.indexOf() и String.substring() методов?

Спасибо!

Ответ №1:

FreeMarker выполняет практически все во время выполнения (кроме базового синтаксического анализа), включая разрешение #include -s и #imports . Так что у вас могут быть такие вещи <#include someVariable> , как <#if condition><#include "this.ftl"></#if> , и т. Д. Поэтому, как правило, невозможно определить, какие зависимости есть у шаблона, и поэтому для этого также нет частного API. Существует неопубликованный API для обхода AST (начиная с Template.getRootTreeNode() ), а затем вы можете попытаться угадать, надеясь, что ваши шаблоны не сложны в этом отношении. (Да, это так @deprecated , но неважно, на данный момент он, безусловно, никогда не будет удален из 2.x.)

Что касается псевдонимов. Макросы, функции, методы-все это просто значения для языка шаблонов. Так что вы можете это сделать <#assign mm = myImport.MyMacro> , а затем просто использовать mm так, как вы бы использовали myImport.MyMacro .

Комментарии:

1. Большое спасибо за ответ @ddekany ! Понял.

2. Есть ли способ получить имена импортированных и включенных шаблонов без написания собственного синтаксического анализатора? Спасибо! @ddekany

3. @RakshitKumar Да, начиная с возвращаемого значения Template.getRootTreeNode() , вы можете пересечь AST. Хотя это будет неудобно (и некоторые классы, возможно, видны в пакете), это все равно проще, чем писать свой собственный синтаксический анализатор.

4. Я не думаю, что полностью понимаю это. После получения корневого узла дерева мне все равно придется написать регулярное выражение или анализатор строк, чтобы получить все имена задействованных(импортированных и включенных) шаблонов, верно? Я хотел спросить, может ли быть способ не использовать этот анализатор регулярных выражений/строк и при этом получить список всех задействованных шаблонов. Спасибо! @ddekany

5. Проверьте указанный API. AST-это результат синтаксического анализа, в этот момент вам ничего не нужно анализировать. Это, конечно, не очень дружелюбный API… Вам нужно искать freemarker.core.Include и/или freemarker.core.LibraryLoad объекты в AST.