package org.ocpsoft.rewrite.faces; import java.util.ArrayList; import java.util.List; import javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import javax.servlet.http.HttpServletRequest; import org.ocpsoft.logging.Logger; import org.ocpsoft.rewrite.context.EvaluationContext; import org.ocpsoft.rewrite.event.Flow; import org.ocpsoft.rewrite.exception.RewriteException; import org.ocpsoft.rewrite.faces.config.PhaseAction; import org.ocpsoft.rewrite.faces.config.PhaseOperation; import org.ocpsoft.rewrite.faces.config.PhaseOperation.DeferredOperation; import org.ocpsoft.rewrite.servlet.RewriteLifecycleContext; import org.ocpsoft.rewrite.servlet.event.BaseRewrite.ServletRewriteFlow; import org.ocpsoft.rewrite.servlet.event.ServletRewrite; import org.ocpsoft.rewrite.servlet.event.SubflowTask; import org.ocpsoft.rewrite.servlet.http.HttpRewriteLifecycleContext; import org.ocpsoft.rewrite.servlet.http.event.HttpServletRewrite; import org.ocpsoft.rewrite.servlet.spi.RewriteResultHandler; /** * @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a> */ public class RewritePhaseListener implements PhaseListener { private static final long serialVersionUID = 6706075446314218089L; private static Logger log = Logger.getLogger(RewritePhaseListener.class); public RewritePhaseListener() { log.info(RewritePhaseListener.class.getSimpleName() + " starting up."); } @Override public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } @Override public void beforePhase(final PhaseEvent event) { if (!PhaseId.RESTORE_VIEW.equals(event.getPhaseId())) { handleBeforePhaseOperations(event); } if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) handleNavigation(event); } @Override public void afterPhase(final PhaseEvent event) { if (!PhaseId.RENDER_RESPONSE.equals(event.getPhaseId())) { handleAfterPhaseOperations(event); handleNavigation(event); } } private void handleBeforePhaseOperations(final PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); HttpServletRequest request = ((HttpServletRequest) facesContext.getExternalContext().getRequest()); ArrayList<DeferredOperation> operations = PhaseOperation.getSortedPhaseOperations(request); if (operations != null) { for (final DeferredOperation deferredOperation : operations) { PhaseOperation<?> operation = deferredOperation.getOperation(); if (operation.getBeforePhases().contains(event.getPhaseId()) || operation.getBeforePhases().contains(PhaseId.ANY_PHASE)) { Flow flow = handlePhaseOperation(deferredOperation); if (flow.is(ServletRewriteFlow.ABORT_REQUEST)) { event.getFacesContext().responseComplete(); } if (flow.is(ServletRewriteFlow.HANDLED)) { break; } } } } } private void handleAfterPhaseOperations(final PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); HttpServletRequest request = ((HttpServletRequest) facesContext.getExternalContext().getRequest()); ArrayList<DeferredOperation> operations = PhaseOperation.getSortedPhaseOperations(request); if (operations != null) { for (final DeferredOperation deferredOperation : operations) { PhaseOperation<?> operation = deferredOperation.getOperation(); if (operation.getAfterPhases().contains(event.getPhaseId()) || operation.getAfterPhases().contains(PhaseId.ANY_PHASE)) { Flow flow = handlePhaseOperation(deferredOperation); if (flow.is(ServletRewriteFlow.ABORT_REQUEST)) { event.getFacesContext().responseComplete(); } if (flow.is(ServletRewriteFlow.HANDLED)) { break; } } } } } private Flow handlePhaseOperation(final DeferredOperation operation) { Flow flow = SubflowTask.perform(operation.getEvent(), operation.getContext(), ServletRewriteFlow.UN_HANDLED, new SubflowTask() { @Override public void performInSubflow(ServletRewrite<?, ?> rewriteEvent, EvaluationContext context) { try { operation.getOperation().performOperation((HttpServletRewrite) rewriteEvent, context); List<RewriteResultHandler> resultHandlers = ((HttpRewriteLifecycleContext) ((HttpServletRewrite) rewriteEvent) .getRequest().getAttribute(RewriteLifecycleContext.LIFECYCLE_CONTEXT_KEY)) .getResultHandlers(); int handlerCount = resultHandlers.size(); for (int i = 0; i < handlerCount; i++) { RewriteResultHandler handler = resultHandlers.get(i); if (handler.handles(operation.getEvent())) handler.handleResult(operation.getEvent()); } } catch (Exception e) { throw new RewriteException("Failed to handle PhaseOperation [" + operation + "]", e); } } }); return flow; } public void handleNavigation(final PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); HttpServletRequest request = ((HttpServletRequest) facesContext.getExternalContext().getRequest()); String navigationCase = (String) request.getAttribute(NavigatingInvocationResultHandler.QUEUED_NAVIGATION); if (navigationCase != null) { request.setAttribute(NavigatingInvocationResultHandler.QUEUED_NAVIGATION, null); NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler(); log.debug("Passing queued " + PhaseAction.class.getName() + " result [" + navigationCase + "] to NavigationHandler.handleNavigation()"); navigationHandler.handleNavigation(facesContext, "", navigationCase); } } }