[jboss-cvs] jboss-seam/src/main/org/jboss/seam/exception ...

Gavin King gavin.king at jboss.com
Mon Jun 25 18:56:49 EDT 2007


  User: gavin   
  Date: 07/06/25 18:56:49

  Added:       src/main/org/jboss/seam/exception          
                        AnnotationErrorHandler.java
                        AnnotationRedirectHandler.java
                        ConfigErrorHandler.java ConfigRedirectHandler.java
                        DebugPageHandler.java ErrorHandler.java
                        ExceptionHandler.java Exceptions.java
                        RedirectHandler.java package-info.java
  Log:
  exception(s)
  
  Revision  Changes    Path
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/AnnotationErrorHandler.java
  
  Index: AnnotationErrorHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import org.jboss.seam.annotations.exception.HttpError;
  
  /**
   * Implements @HttpError
   * 
   * @see HttpError
   * @author Gavin King
   *
   */
  public class AnnotationErrorHandler extends ErrorHandler
  {
     @Override
     public boolean isHandler(Exception e)
     {
        return e.getClass().isAnnotationPresent(HttpError.class);
     }
     
     @Override
     protected String getMessage(Exception e)
     {
        return e.getClass().getAnnotation(HttpError.class).message();
     }
     
     @Override
     protected int getCode(Exception e)
     {
        return e.getClass().getAnnotation(HttpError.class).errorCode();
     }
     
     @Override
     @SuppressWarnings("deprecation")
     protected boolean isEnd(Exception e)
     {
        return e.getClass().getAnnotation(HttpError.class).end();
     }
     
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/AnnotationRedirectHandler.java
  
  Index: AnnotationRedirectHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import javax.faces.application.FacesMessage;
  import javax.faces.application.FacesMessage.Severity;
  
  import org.jboss.seam.annotations.exception.Redirect;
  
  /**
   * Implements @Redirect
   * 
   * @see Redirect
   * @author Gavin King
   *
   */
  public class AnnotationRedirectHandler extends RedirectHandler
  {
     @Override
     public boolean isHandler(Exception e)
     {
        return e.getClass().isAnnotationPresent(Redirect.class);
     }
     
     @Override
     protected String getMessage(Exception e)
     {
        return e.getClass().getAnnotation(Redirect.class).message();
     }
     
     @Override
     protected Severity getMessageSeverity(Exception e)
     {
        return FacesMessage.SEVERITY_INFO;
     }
     
     @Override
     protected String getViewId(Exception e)
     {
        return e.getClass().getAnnotation(Redirect.class).viewId();
     }
     
     @Override
     @SuppressWarnings("deprecation")
     protected boolean isEnd(Exception e)
     {
        return e.getClass().getAnnotation(Redirect.class).end();
     }
     
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/ConfigErrorHandler.java
  
  Index: ConfigErrorHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  /**
   * Implements <http-error/> for pages.xml
   * 
   * @author Gavin King
   *
   */
  public final class ConfigErrorHandler extends ErrorHandler
  {
     private final String message;
     private final boolean conversation;
     private final Class clazz;
     private final int code;
  
     public ConfigErrorHandler(String message, boolean conversation, Class clazz, int code)
     {
        this.message = message;
        this.conversation = conversation;
        this.clazz = clazz;
        this.code = code;
     }
  
     @Override
     protected String getMessage(Exception e)
     {
        return message;
     }
  
     @Override
     protected int getCode(Exception e)
     {
        return code;
     }
  
     @Override
     public boolean isHandler(Exception e)
     {
        return clazz.isInstance(e);
     }
  
     @Override
     protected boolean isEnd(Exception e)
     {
        return conversation;
     }
  
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/ConfigRedirectHandler.java
  
  Index: ConfigRedirectHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import javax.faces.application.FacesMessage.Severity;
  
  /**
   * Implements <redirect/> for pages.xml
   * 
   * @author Gavin King
   *
   */
  public final class ConfigRedirectHandler extends RedirectHandler
  {
     private final String id;
     private final Class clazz;
     private final boolean conversation;
     private final String message;
     private final Severity messageSeverity;
  
     public ConfigRedirectHandler(String id, Class clazz, boolean conversation, String message, Severity messageSeverity)
     {
        this.id = id;
        this.clazz = clazz;
        this.conversation = conversation;
        this.message = message;
        this.messageSeverity = messageSeverity;
     }
  
     @Override
     protected String getMessage(Exception e)
     {
        return message;
     }
  
     @Override
     protected String getViewId(Exception e)
     {
        return id;
     }
  
     @Override
     public boolean isHandler(Exception e)
     {
        return clazz.isInstance(e);
     }
  
     @Override
     protected boolean isEnd(Exception e)
     {
        return conversation;
     }
  
     @Override
     public Severity getMessageSeverity(Exception e)
     {
        return messageSeverity;
     }
  
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/DebugPageHandler.java
  
  Index: DebugPageHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.faces.FacesManager;
  import org.jboss.seam.faces.RedirectException;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  
  /**
   * Implements automagic redirection to the Seam debug page.
   * 
   * @author Gavin King
   *
   */
  public class DebugPageHandler extends ExceptionHandler
  {
  
     private static final LogProvider log = Logging.getLogProvider(DebugPageHandler.class);
  
     @Override
     public void handle(Exception e) throws Exception
     {
        log.error("redirecting to debug page", e);
        org.jboss.seam.faces.Redirect redirect = org.jboss.seam.faces.Redirect.instance();
        redirect.setViewId("/debug.xhtml");
        FacesManager manager = FacesManager.instance();
        manager.beforeRedirect("/debug.xhtml");
        redirect.setParameter( manager.getConversationIdParameter(), manager.getCurrentConversationId() );
        
        try
        {
           redirect.execute();
        }
        catch (RedirectException re)
        {
           //do nothing
           log.debug("could not redirect", re);
        }
        
        Contexts.getConversationContext().flush();
     }
  
     @Override
     public boolean isHandler(Exception e)
     {
        return true;
     }
     
     @Override
     public String toString()
     {
        return "DebugPageHandler";
     }
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/ErrorHandler.java
  
  Index: ErrorHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.core.Interpolator;
  
  /**
   * Base implementation of HTTP error exception handlers.
   * 
   * @author Gavin King
   *
   */
  public abstract class ErrorHandler extends ExceptionHandler
  {
  
     protected abstract int getCode(Exception e);
     protected abstract String getMessage(Exception e);
     protected abstract boolean isEnd(Exception e);
  
     @Override
     public void handle(Exception e) throws Exception
     {
        if ( Contexts.isConversationContextActive() && isEnd(e) ) 
        {
           Conversation.instance().end();
        }
        
        String msg = getDisplayMessage( e, getMessage(e) );
        msg = msg==null ? null : Interpolator.instance().interpolate(msg);
        error( getCode(e), msg );
     }
  
     @Override
     public String toString()
     {
        return "ErrorHandler";
     }
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/ExceptionHandler.java
  
  Index: ExceptionHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import org.jboss.seam.faces.Navigator;
  
  /**
   * An element of the chain that knows how to handle a 
   * specific exception type.
   * 
   * @author Gavin King
   *
   */
  public abstract class ExceptionHandler extends Navigator
  {
     public abstract void handle(Exception e) throws Exception;
     public abstract boolean isHandler(Exception e);
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/Exceptions.java
  
  Index: Exceptions.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.List;
  
  import javax.faces.application.FacesMessage;
  import javax.faces.application.FacesMessage.Severity;
  
  import org.dom4j.DocumentException;
  import org.dom4j.Element;
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Create;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.intercept.BypassInterceptors;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Events;
  import org.jboss.seam.core.Init;
  import org.jboss.seam.core.ResourceLoader;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.navigation.Pages;
  import org.jboss.seam.util.EJB;
  import org.jboss.seam.util.Reflections;
  import org.jboss.seam.util.Strings;
  import org.jboss.seam.util.XML;
  
  /**
   *  Manages the exception handler chain
   * 
   * @author Gavin King
   */
  @Scope(ScopeType.APPLICATION)
  @BypassInterceptors
  @Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
  @Name("org.jboss.seam.exceptions.exceptions")
  public class Exceptions
  {
     private static final LogProvider log = Logging.getLogProvider(Exceptions.class);
     
     private List<ExceptionHandler> exceptionHandlers = new ArrayList<ExceptionHandler>();
     
     public void handle(Exception e) throws Exception
     {
        if ( Contexts.isConversationContextActive() )
        {
           Contexts.getConversationContext().set("org.jboss.seam.exception", e);
        }
        
        //build a list of the nested exceptions
        List<Exception> causes = new ArrayList<Exception>();
        for (Exception cause=e; cause!=null; cause=EJB.getCause(cause))
        {
           causes.add(cause);
        }
        //try to match each handler in turn
        for (ExceptionHandler eh: exceptionHandlers)
        {
           //Try to handle most-nested exception before least-nested
           for (int i=causes.size()-1; i>=0; i--)
           {
              Exception cause = causes.get(i);
              if ( eh.isHandler(cause) )
              {
                 if ( Contexts.isConversationContextActive() )
                 {
                    Contexts.getConversationContext().set("org.jboss.seam.handledException", cause);
                 }
                 eh.handle(cause);
                 Events.instance().raiseEvent("org.jboss.seam.exceptionHandled." + cause.getClass().getName(), cause);
                 Events.instance().raiseEvent("org.jboss.seam.exceptionHandled", cause);
                 return;
              }
           }
        }
        
        //finally, rethrow it, since no handler was found
        Events.instance().raiseEvent("org.jboss.seam.exceptionNotHandled", e);
        throw e;
     }
     
     @Create
     public void initialize() throws Exception 
     {
        List<ExceptionHandler> deferredHandlers = new ArrayList<ExceptionHandler>();
        
        deferredHandlers.add(parse("/WEB-INF/exceptions.xml")); // deprecated
        
        for (String pageFile: Pages.instance().getResources()) 
        {
            deferredHandlers.add(parse(pageFile));
        }
                      
        addHandler(new AnnotationRedirectHandler());
        addHandler(new AnnotationErrorHandler());
        
        if (Init.instance().isDebug()) 
        {
           addHandler(new DebugPageHandler());
        }
              
        for (ExceptionHandler handler: deferredHandlers) 
        {
            addHandler(handler);
        }
     }
  
     private void addHandler(ExceptionHandler handler)
     {
        if (handler!=null) exceptionHandlers.add(handler);
     }
     
     private ExceptionHandler parse(String fileName) throws DocumentException, ClassNotFoundException
     {
        ExceptionHandler anyhandler = null;
        InputStream stream = ResourceLoader.instance().getResourceAsStream(fileName);
        if (stream!=null)
        {
           log.debug("reading exception mappings from " + fileName);
           List<Element> elements = XML.getRootElement(stream).elements("exception");
           for (final Element exception: elements)
           {
              String className = exception.attributeValue("class");
              if (className==null)
              {
                 anyhandler = createHandler(exception, Exception.class);
              }
              else
              {
                 ExceptionHandler handler = createHandler( exception, Reflections.classForName(className) );
                 if (handler!=null) exceptionHandlers.add(handler);
              }
           }
        }
        return anyhandler;
     }
  
     private ExceptionHandler createHandler(Element exception, final Class clazz)
     {
        final boolean endConversation = exception.elementIterator("end-conversation").hasNext();
        
        Element redirect = exception.element("redirect");
        if (redirect!=null)
        {
           final String viewId = redirect.attributeValue("view-id");
           Element messageElement = redirect.element("message");
           final String message = messageElement==null ? null : messageElement.getTextTrim();
           String severityName = messageElement==null ? null : messageElement.attributeValue("severity");
           Severity severity = severityName==null ? 
                    FacesMessage.SEVERITY_INFO : 
                    Pages.getFacesMessageValuesMap().get( severityName.toUpperCase() );
           return new ConfigRedirectHandler(viewId, clazz, endConversation, message, severity);
        }
        
        Element error = exception.element("http-error");
        if (error!=null)
        {
           String errorCode = error.attributeValue("error-code");
           final int code = Strings.isEmpty(errorCode) ? 
                 500 : Integer.parseInt(errorCode);
           Element messageElement = error.element("message");
           final String message = messageElement==null ? null : messageElement.getTextTrim();
           return new ConfigErrorHandler(message, endConversation, clazz, code);
        }
        
        return null;
     }
     
     /**
      * @return the exception handler list, which supports addition and removal
      *         of handlers
      */
     public List<ExceptionHandler> getHandlers()
     {
        return exceptionHandlers;
     }
  
     public static Exceptions instance()
     {
        if ( !Contexts.isApplicationContextActive() )
        {
           throw new IllegalStateException("No active application context");
        }
        return (Exceptions) Component.getInstance(Exceptions.class, ScopeType.APPLICATION);
     }
  
  }
  
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/RedirectHandler.java
  
  Index: RedirectHandler.java
  ===================================================================
  package org.jboss.seam.exception;
  
  import javax.faces.application.FacesMessage.Severity;
  import javax.faces.context.FacesContext;
  import javax.servlet.http.HttpServletRequest;
  
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.Conversation;
  import org.jboss.seam.faces.RedirectException;
  import org.jboss.seam.log.LogProvider;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.navigation.Pages;
  
  /**
   * Base implementation of redirection exception handlers.
   * 
   * @author Gavin King
   *
   */
  public abstract class RedirectHandler extends ExceptionHandler
  {
  
     private static final LogProvider log = Logging.getLogProvider(RedirectHandler.class);
  
     protected abstract String getViewId(Exception e);
     protected abstract String getMessage(Exception e);
     protected abstract boolean isEnd(Exception e);
     protected abstract Severity getMessageSeverity(Exception e);
  
     @Override
     public void handle(Exception e) throws Exception
     {
        String viewId = getViewId(e);
        if (viewId==null)
        {
           //we want to perform a redirect straight back to the current page
           //there is no ViewRoot available, so lets do it the hard way
           String servletPath = ( (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest() ).getServletPath();
           viewId = servletPath.substring(0, servletPath.lastIndexOf('.')) + Pages.getSuffix();
        }
        
        addFacesMessage( getDisplayMessage(e, getMessage(e)), getMessageSeverity(e), null, e );
        
        if ( Contexts.isConversationContextActive() && isEnd(e) ) 
        {
           Conversation.instance().end();
        }
        
        try
        {
           redirect(viewId, null);
        }
        catch (RedirectException re)
        {
           //do nothing
           log.debug("could not redirect", re);
        }
     }
  
     @Override
     public String toString()
     {
        return "RedirectHandler";
     }
  }
  
  
  1.1      date: 2007/06/25 22:56:49;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/exception/package-info.java
  
  Index: package-info.java
  ===================================================================
  /**
   * Implementation of Seam exception handling for JSF.
   */
  package org.jboss.seam.exception;
  
  
  
  



More information about the jboss-cvs-commits mailing list