Управление статическими ресурсами JSF2 - комбинированное, сжатое

Кто-нибудь знает о методе динамического объединения / минимизации всех ресурсов h: outputStylesheet, а затем объединения / минимизации всех ресурсов h: outputScript на этапе рендеринга? Объединенный / уменьшенный ресурс, вероятно, должен был бы быть кэширован с ключом, основанным на объединенной строке ресурса или чем-то, чтобы избежать чрезмерной обработки.

Если эта функция не существует, я бы хотел поработать над ней. У кого-нибудь есть идеи, как лучше всего реализовать что-то подобное? Полагаю, что сервлетный фильтр будет работать, но фильтр должен будет выполнять больше работы, чем необходимо - в основном, анализируя весь вывод и заменяя совпадения. Реализация чего-либо на этапе рендеринга выглядит так, как будто это будет работать лучше, поскольку все статические ресурсы доступны без разбора всего вывода.

Спасибо за любые предложения!

Редактировать: Чтобы показать, что я не ленивый и действительно буду работать над этим с некоторыми рекомендациями, вот заглушка, которая захватывает имя / библиотеку ресурсов сценариев, а затем удаляет их из представления. Как вы видите, у меня есть несколько вопросов о том, что делать дальше ... я должен сделать http-запросы и объединить ресурсы, затем объединить их и сохранить в кэш ресурсов?

package com.davemaple.jsf.listener;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.event.PreRenderViewEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;

import org.apache.log4j.Logger;

/**
 * A Listener that combines CSS/Javascript Resources
 * 
 * @author David Maple<[email protected]>
 *
 */
public class ResourceComboListener implements PhaseListener, SystemEventListener {

    private static final long serialVersionUID = -8430945481069344353L;
    private static final Logger LOGGER = Logger.getLogger(ResourceComboListener.class);

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    /*
     * (non-Javadoc)
     * @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
     */
    public void afterPhase(PhaseEvent event) {
        FacesContext.getCurrentInstance().getViewRoot().subscribeToViewEvent(PreRenderViewEvent.class, this);
    }

    /*
     * (non-Javadoc)
     * @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
     */
    public void beforePhase(PhaseEvent event) {
        //nothing here
    }

    /*
     * (non-Javadoc)
     * @see javax.faces.event.SystemEventListener#isListenerForSource(java.lang.Object)
     */
    public boolean isListenerForSource(Object source) {
        return (source instanceof UIViewRoot);
    }

    /*
     * (non-Javadoc)
     * @see javax.faces.event.SystemEventListener#processEvent(javax.faces.event.SystemEvent)
     */
    public void processEvent(SystemEvent event) throws AbortProcessingException {
        FacesContext context = FacesContext.getCurrentInstance();
        UIViewRoot viewRoot = context.getViewRoot();
        List<UIComponent> scriptsToRemove = new ArrayList<UIComponent>();

        if (!context.isPostback()) {

            for (UIComponent component : viewRoot.getComponentResources(context, "head")) {
                if (component.getClass().equals(UIOutput.class)) {
                    UIOutput uiOutput = (UIOutput) component;

                    if (uiOutput.getRendererType().equals("javax.faces.resource.Script")) {
                        String library = uiOutput.getAttributes().get("library").toString();
                        String name = uiOutput.getAttributes().get("name").toString();

                        // make https requests to get the resources?
                        // combine then and save to resource cache?
                        // insert new UIOutput script?

                        scriptsToRemove.add(component);
                    }


                }
            }

            for (UIComponent component : scriptsToRemove) {
                viewRoot.getComponentResources(context, "head").remove(component);
            }

        }
    }

}

Ответы на вопрос(4)

Ваш ответ на вопрос