Кто-нибудь знает о способе динамического объединения/минимизации всех ресурсов h: outputStylesheet, а затем объединения/минимизации всех ресурсов h: outputScript в фазе визуализации? Предполагаемый/минимизированный ресурс, вероятно, нужно будет кэшировать с помощью ключа на основе объединенной строки ресурсов или чего-то, чтобы избежать чрезмерной обработки.
Если эта функция не существует, я бы хотел поработать над ней. У кого-нибудь есть идеи о том, как лучше всего реализовать что-то подобное. Сервлет-фильтр работал бы, я полагаю, но фильтр должен будет выполнять больше работы, чем необходимо, - в основном, анализируя весь вывод и заменяя совпадения. Реализация чего-то в фазе рендеринга кажется такой, что она будет работать лучше, поскольку все статические ресурсы доступны без необходимости синтаксического анализа всего вывода.
Спасибо за любые предложения!
Изменить: Чтобы показать, что я не ленив и действительно буду работать над этим с некоторыми указаниями, вот заглушка, которая захватывает Script имя/библиотеку ресурсов, а затем удаляет их из представления, Как вы можете видеть, у меня есть некоторые вопросы о том, что делать дальше... Должен ли я создавать 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);
}
}
}
}