Package org.springframework.springfaces.exceptionhandler

Source Code of org.springframework.springfaces.exceptionhandler.SpringFacesExceptionHandlerSupport

/*
* Copyright 2010-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.springfaces.exceptionhandler;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.el.EvaluationException;
import javax.faces.event.ExceptionQueuedEvent;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.springfaces.FacesWrapperFactory;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

/**
* {@link FacesWrapperFactory} for a JSF {@link javax.faces.context.ExceptionHandler} that offers extended Spring
* support. All Spring Beans that implement {@link ExceptionHandler} with a matching generic type are considered. Beans
* are ordered using {@link AnnotationAwareOrderComparator}, once the exception has been {@link ExceptionHandler#handle
* handled} subsequent beans will not be called.
*
* @author Phillip Webb
*/
@SuppressWarnings({ "deprecation", "rawtypes" })
public class SpringFacesExceptionHandlerSupport implements FacesWrapperFactory<javax.faces.context.ExceptionHandler>,
    ApplicationListener<ContextRefreshedEvent>, ApplicationContextAware {

  private static Set<Class<?>> EXCEPTIONS_TO_UNWRAP;
  static {
    HashSet<Class<?>> unwrappedExceptions = new HashSet<Class<?>>();
    unwrappedExceptions.add(FacesException.class);
    unwrappedExceptions.add(ELException.class);
    unwrappedExceptions.add(EvaluationException.class);
    EXCEPTIONS_TO_UNWRAP = Collections.unmodifiableSet(unwrappedExceptions);
  }

  private ApplicationContext applicationContext;

  private List<ExceptionHandler> exceptionHandlers;

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }

  public void onApplicationEvent(ContextRefreshedEvent event) {
    ApplicationContext applicationContext = event.getApplicationContext();
    if (applicationContext == this.applicationContext) {
      collectExceptionHandlerBeans();
    }
  }

  private void collectExceptionHandlerBeans() {
    this.exceptionHandlers = new ArrayList<ExceptionHandler>(BeanFactoryUtils.beansOfTypeIncludingAncestors(
        this.applicationContext, ExceptionHandler.class, true, true).values());
    Collections.sort(this.exceptionHandlers, new AnnotationAwareOrderComparator());
  }

  public javax.faces.context.ExceptionHandler newWrapper(Class<?> typeClass,
      javax.faces.context.ExceptionHandler wrapped) {
    return new SpringFacesExceptionHandler(wrapped);
  }

  protected class SpringFacesExceptionHandler extends ExceptionHandlerWrapper {

    private javax.faces.context.ExceptionHandler wrapped;

    /**
     * Create a new {@link SpringFacesExceptionHandlerSupport} instance.
     * @param wrapped the wrapped JSF exception handler
     */
    public SpringFacesExceptionHandler(javax.faces.context.ExceptionHandler wrapped) {
      Assert.notNull(wrapped, "Wrapped must not be null");
      this.wrapped = wrapped;
    }

    @Override
    public javax.faces.context.ExceptionHandler getWrapped() {
      return this.wrapped;
    }

    @Override
    public void handle() throws FacesException {
      Iterator<ExceptionQueuedEvent> events = getUnhandledExceptionQueuedEvents().iterator();
      while (events.hasNext()) {
        if (handle(events.next())) {
          events.remove();
        }
      }
      super.handle();
    }

    @SuppressWarnings("unchecked")
    private boolean handle(ExceptionQueuedEvent event) {
      Throwable exception = getRootCause(event.getContext().getException());
      Class<? extends Throwable> exceptionType = exception.getClass();
      for (ExceptionHandler handler : SpringFacesExceptionHandlerSupport.this.exceptionHandlers) {
        Class<?> handlerGeneric = GenericTypeResolver.resolveTypeArgument(handler.getClass(),
            ExceptionHandler.class);
        if (handlerGeneric == null || handlerGeneric.isAssignableFrom(exceptionType)) {
          try {
            if (handler.handle(exception, event)) {
              return true;
            }
          } catch (Exception e) {
            ReflectionUtils.rethrowRuntimeException(e);
          }
        }
      }
      return false;
    }

    @Override
    public Throwable getRootCause(Throwable throwable) {
      // Overridden to support unwrapping of EvaluationExceptions.
      Assert.notNull(throwable, "Throwable must not be null");
      while (EXCEPTIONS_TO_UNWRAP.contains(throwable.getClass())) {
        throwable = throwable.getCause();
      }
      return super.getRootCause(throwable);
    }
  }
}
TOP

Related Classes of org.springframework.springfaces.exceptionhandler.SpringFacesExceptionHandlerSupport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.