Как получить доступ к статическим членам в шаблоне Velocity?

Я не уверен, есть ли способ сделать это в Velocity или нет:

У меня есть Пользователь POJO, у которого есть свойство с именем Status, которое выглядит как enum (но это не так, поскольку я застрял на Java 1.4), определение выглядит примерно так:

public class User  {

    // default status to User
    private Status status = Status.USER;

    public void setStatus(Status status) {
        this.status = status;
    }

    public Status getStatus() {
        return status;
    }

И Status является статическим внутренним классом:

public static final class Status {

    private String statusString;

    private Status(String statusString) {
        this.statusString = statusString;
    }

    public final static Status USER = new Status("user");
    public final static Status ADMIN = new Status("admin");
    public final static Status STATUS_X = new Status("blah");

    //.equals() and .hashCode() implemented as well
}

С помощью этого шаблона пользовательский статус может быть легко протестирован в условном выражении, например

if(User.Status.ADMIN.equals(user.getStatus())) ...

... без необходимости ссылаться на какие-либо константы для идентификатора статуса, любых магических чисел и т.д.

Однако я не могу понять, как проверить эти условные условия в моем шаблоне Velocity с VTL. Я бы хотел просто напечатать простую строку на основе состояния пользователя, например:

Welcome <b>${user.name}</b>!
<br/>
<br/>

#if($user.status == com.company.blah.User.Status.USER)
    You are a regular user
#elseif($user.status == com.company.blah.User.Status.ADMIN)
    You are an administrator
#etc...

#end

Но это вызывает исключение, которое выглядит как org.apache.velocity.exception.ParseErrorException: Encountered "User" at webpages/include/dashboard.inc[line 10, column 21] Was expecting one of: "[" ...

Из Руководство пользователя VTL, нет упоминания о доступе к классу Java/статическому члену непосредственно в VTL, кажется, что правая рука (RHS) условного выражения может быть только литералом числа, строковым литералом, ссылкой на свойство или ссылкой на метод.

Итак, есть ли способ получить доступ к статическим свойствам/ссылкам Java в шаблоне Velocity? Я знаю, что в качестве обходного пути я мог бы вставить идентификатор статуса или какой-либо другой идентификатор в качестве ссылки в моем контроллере (это веб-приложение MVC, использующее технологию Velocity в качестве технологии просмотра), но я сильно не хочу встраивать какую-либо магию числа или константы в уровне представления.

Ответ 1

Я выяснил обходное решение, которое позволяет мне добавить каждый объект User.Status в контекст Velocity, который избегает любых ссылок на константы или магические числа в шаблоне.

На стороне контроллера /Java:

// put the statuses directly into the model
Map statusMap = new HashMap();
statusMap.put("user", User.Status.USER);
statusMap.put("groupOperator", User.Status.ADMIN);
...
modelAndView.addObject("statusmap", statusMap);

И затем в шаблоне эти значения можно ссылаться так:

#if($user.status == $statusmap.user)
   You are a regular user
#elseif($user.status == $statusmap.admin)
    You are an administrator
##etc...
#end

Ответ 2

Да, Velocity не изначально ищет классы и пакеты. Вы можете сделать то, что вы сделали, или использовать класс FieldMethodizer для автоматизации этого. Еще одним вариантом будет FieldTool в VelocityTools 2.0.

Ответ 3

Попытайтесь использовать FieldMethodizer of Velocity, это не лучшее решение, но вы можете что-то сделать.

С помощью этого класса вы можете вызвать статические общедоступные константы, см. ссылку:

API FieldMethodizer