Можно ли включить все файлы javascripts из одной папки в JSF? - PullRequest
4 голосов
/ 19 декабря 2010

Я использую JSF 2.0 и ищу способ включить все javascript-коды из заданной папки на странице, то есть сделать что-то вроде

<h:outputScript library="javascript" name="*.js" target="head" />

Возможно ли такое вообще?Должен ли я написать собственный компонент, используя Java-код для достижения этой цели?

Спасибо за вашу помощь,
Sébastien Tromp

Ответы [ 2 ]

3 голосов
/ 20 декабря 2010

Хорошая идея.Это не поддерживается API JSF, но теоретически это возможно при использовании специального средства визуализации сценариев.Я немного играл вокруг, и это действительно возможно.Просто создайте MultiScriptRenderer, который extends ScriptRenderer и переопределите encodeEnd(), чтобы проверить, содержит ли атрибут name подстановочный знак *, и затем обработайте его соответствующим образом путем сканирования файлов, соответствующих этому шаблону, в папке ресурсов..

Вот пример запуска:

package com.example;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import com.sun.faces.renderkit.html_basic.ScriptRenderer;

public class MultiScriptRenderer extends ScriptRenderer {

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        Map<String, Object> attributes = component.getAttributes();
        String name = (String) attributes.get("name");
        if (name.contains("*")) {
            String pattern = name.replace(".", "\\.").replace("*", ".*");
            String library = (String) attributes.get("library");
            File root = new File(context.getExternalContext().getRealPath("/resources/" + (library != null ? library : "")));
            for (File file : root.listFiles()) {
                if (file.getName().matches(pattern)) {
                    attributes.put("name", file.getName());
                    super.encodeEnd(context, component);
                }
            }
            attributes.put("name", name); // Put original name back. You never know.
        } else {
            super.encodeEnd(context, component);
        }
    }
}

Зарегистрируйте его в faces-config.xml следующим образом (Извините, @FacesRenderer аннотация не собираетсяработать до тех пор, пока это не будет исправлено в JSF 2.2 для этого конкретного случая, см. также JSF, выпуск 1748 ) :

<render-kit>
    <renderer>
        <component-family>javax.faces.Output</component-family>
        <renderer-type>javax.faces.resource.Script</renderer-type>
        <renderer-class>com.example.MultiScriptRenderer</renderer-class>
    </renderer>
</render-kit>

Здесь отлично работает на Mojarra 2.0.3.Вы можете использовать шаблоны, такие как *.js и prefix*.js.Конкретный пример кода тесно связан с конкретной реализацией JSF для сохранения шаблонного кода.Также требуется, чтобы WAR развертывался при развертывании, иначе просмотр каталога по File#listFiles() будет невозможен (что исключает определенные (более старые) версии / конфигурации servletcontainer).Для других реализаций JSF вам придется вместо этого расширить ScriptRenderer или написать совершенно новую, если вы хотите быть независимыми от реализации (хотя это должно быть довольно просто, просто посмотрите на стандартный ScriptRenderer источник, если вы застряли).

3 голосов
/ 20 декабря 2010

Я не проверял это, но если подстановочные знаки не принимаются, вы можете получить список файлов с помощью кода Java в компоненте поддержки и вставить их в голову, используя c:forEach или ui:repeat, например:

<ui:repeat value="#{bean.files}" var="file">
    <h:outputScript library="javascript" name="#{file}" target="head" />
</ui:repeat>

Обратите внимание, что вы не можете указать абсолютные пути к h:outputScript, но вы должны извлечь из них префикс (часть, предшествующая пути ресурсов JSF).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...