Как проверить правильность выражений EL статически? - PullRequest
5 голосов
/ 14 октября 2010

В нашем веб-приложении мы провели некоторый рефакторинг для Java-бинов, и из-за этого рефакторинга некоторые действия / получатели больше не доступны. Например, в следующем примере:

public class MyBean implements Serializable {

    // Old name
    // public String getFoo() { return "foo"; }

    // New name
    public String getBar() { return "bar"; }

}

Если мой код JSF по-прежнему выглядит так:

<h:inputText value="#{myBean.foo}" .../>

тогда будет сгенерировано исключение.

Мое главное беспокойство заключается в том, что некоторые выражения EL могут теперь указывать на несуществующие методы в Java-бине, и я вижу это только при просмотре соответствующей страницы. Сложнее становится, когда выражение EL находится в части, которая отображается в определенных условиях и / или воспроизводится Ajax.

Итак, мой вопрос: как я могу статически проверить правильность этих выражений EL?

Я проверил инструмент JSFUnit , поскольку он предоставляет такую ​​утилиту. Поэтому я попробовал этот пример , но, похоже, он работает не так, как ожидалось. На простой тестовой странице, с несколькими выражениями EL (некоторые правильные, другие неправильные с несуществующими компонентами и / или методами), тест завершается успешно, что неверно.

Действительно важное замечание: мои бины определены в моей конфигурации Spring, а не в faces-config.xml.

Также обратите внимание, что мне просто нужно проверить, относится ли выражение EL к существующему компоненту и методу, и необязательно, что это действие будет выполнено правильно ...

Техническая информация:

Java 1.6, Spring 2.5, JSF 1.2, EL Functor , Facelets и Richfaces 3.3

1 Ответ

1 голос
/ 15 октября 2010

Я не нашел инструмент, который соответствует моим требованиям.Поэтому я написал небольшой боб в своем приложении.Этот bean-компонент предоставит действие, которое будет читать каталог и анализировать каждый файл .xhtml в нем (и делать это рекурсивно).Конечно, мне придется запустить мое приложение (поэтому анализ не является на самом деле статичным), но преимущество этого решения в том, что у меня будет доступ к ELContext и ELExpressionFactory, которые я действительно использую в своем веб-приложенииоба связаны с моим контекстом Spring.

Вот интересная часть кода:

// Analyse a XHTML file
private void analyzeXHTMLFile(File f) throws IOException {
    List<String> lines = FileUtils.readLines(f);
    for (String l : lines) {
        List<String> els = getEL(l);
        for (String el : els) {
            evaluateEL(el);
        }
    }
}

// Get a List of EL on the line.
private List<String> getEL(String line) {
    List<String> el = new ArrayList<String>();
    int i = line.indexOf("#{");
    if (i == -1) {
        return el;
    }
    while (i != -1) {
        int j = line.indexOf("}", i);
        if (j == -1) {
            return el;
        }
        el.add(line.substring(i, j + 1));
        i = line.indexOf("#{", i + 1);
    }
    return el;
}

// Evaluate the EL
private void evaluateEL(String el) {
    FacesContext context = FacesContext.getCurrentInstance();
    ELContext elContext = context.getELContext();
    ValueExpression ve = context.getApplication().getExpressionFactory().createValueExpression(elContext, el, Object.class);
    if (ve != null) {
        Object o = null;
        try {
            o = ve.getValue(elContext);
        } catch (PropertyNotFoundException pnfe) {
            // Handle this error
        }
        if (o == null) {
            // Handle another error
        }
    }
}
...