package org.seasar.jsf.runtime;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.faces.context.ExternalContext;
import javax.servlet.http.HttpServletRequest;

import org.seasar.jsf.ErrorPageManager;
import org.seasar.jsf.JsfConstants;
import org.seasar.jsf.util.ExternalContextUtil;

/**
 * @author higa
 *
 */
public class ErrorPageManagerImpl implements ErrorPageManager {

	private Map locations = new HashMap();

	public void addErrorPage(Class exceptionType, String location) {
		locations.put(exceptionType, location);
	}

	public boolean handleException(Throwable exception, ExternalContext extContext) throws IOException {
		String location = getLocation(exception.getClass());
		if (location == null) {
			return false;
		}
		HttpServletRequest request = ExternalContextUtil.getRequest(extContext);
		request.setAttribute(JsfConstants.ERROR_EXCEPTION, exception);
		request.setAttribute(JsfConstants.ERROR_EXCEPTION_TYPE, exception.getClass());
		request.setAttribute(JsfConstants.ERROR_MESSAGE, exception.getMessage());
		extContext.dispatch(location);
		return true;
	}
	
	protected String getLocation(Class exceptionType) {
		Class clazz = exceptionType;
		String location = (String) locations.get(clazz);
		while (location == null && !clazz.equals(Throwable.class)) {
			clazz = clazz.getSuperclass();
			location = (String) locations.get(clazz);
		}
		return location;
	}
}
