BortalExceptionHandler.java 2.8 KB
package fi.insomnia.bortal.exceptions;

import java.util.Iterator;
import java.util.Map;

import javax.ejb.AccessLocalException;
import javax.ejb.EJBAccessException;
import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BortalExceptionHandler extends ExceptionHandlerWrapper {

	private static final Logger logger = LoggerFactory.getLogger(BortalExceptionHandler.class);
	private final ExceptionHandler wrapped;

	public BortalExceptionHandler(ExceptionHandler wrapped) {
		this.wrapped = wrapped;
	}

	@Override
	public ExceptionHandler getWrapped() {

		return wrapped;
	}

	@Override
	public void handle() throws FacesException {
		Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
		while (i.hasNext()) {

			ExceptionQueuedEvent event = i.next();
			ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
			Throwable t = context.getException();

			logger.debug("Found exception! handing it: {}", t.getClass().toString());
			if (t instanceof ViewExpiredException) {

				errorpage(i, t, "viewExpired");
			}
			Throwable cause = t.getCause();
			for (int loop = 0; loop < 20 && cause != null; ++loop) {
				logger.debug("Cause not null, but {}: {}, checking" + cause.getClass(), cause.getMessage());
				if (cause instanceof EJBAccessException ||
						cause instanceof AccessLocalException) {
					logger.debug("Found Permission Denied cause: {}, {}", cause.getClass(), cause.getMessage());
					// errorpage(i, t, "permissionDenied");

				}
				cause = cause.getCause();
			}
		}

		// At this point, the queue will not contain any ViewExpiredEvents.

		// Therefore, let the parent handle them.

		getWrapped().handle();

	}

	private void errorpage(Iterator<ExceptionQueuedEvent> i, Throwable t, String navigateTo) {
		logger.info("navigating to {} because root exception: {}", navigateTo, t.getClass());
		ViewExpiredException vee = null;
		if (t instanceof ViewExpiredException) {
			vee = (ViewExpiredException) t;
		}

		FacesContext fc = FacesContext.getCurrentInstance();
		Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
		NavigationHandler nav = fc.getApplication().getNavigationHandler();

		try {
			// Push some useful stuff to the request scope for
			// use in the page
			if (vee != null) {
				requestMap.put("currentViewId", vee.getViewId());
			}
			nav.handleNavigation(fc, null, navigateTo);
			fc.renderResponse();
		} finally {
			i.remove();
		}
	}
}