001    package hirondelle.web4j.model;
002    
003    import java.io.Serializable;
004    import java.util.List;
005    
006    import javax.servlet.ServletException;
007    
008    /**
009     Base class for most exceptions defined by WEB4J.  
010    
011     <P>Differs from most exception classes in that multiple error 
012     messages may be used, instead of just one. Used in JSPs to inform the user of 
013     error conditions, usually related to user input validations.
014     
015     <P>This class is {@link Serializable}, since all {@link Throwable}s are serializable.
016    */
017    public class AppException extends ServletException implements MessageList { 
018      
019      /** No-argument constructor. */
020      public AppException(){
021        super();
022      }
023      
024      /**
025       Constructor.
026        
027       @param aMessage text describing the problem. Must have content.
028       @param aThrowable root cause underlying the problem.
029      */
030      public AppException(String aMessage, Throwable aThrowable){
031        super(aMessage, aThrowable);
032        add(aMessage);
033        //using instanceof is distasteful, but overloading constructors,
034        //that is, defining a second ctor(String, AppException), does not work
035        if ( aThrowable instanceof AppException ) {
036          add( (AppException)aThrowable );
037        }
038      }
039    
040      public final void add(String aErrorMessage){
041        fErrorMessages.add(aErrorMessage);
042      }
043    
044      public final void add(String aErrorMessage, Object... aParams){
045        fErrorMessages.add(aErrorMessage, aParams);
046      }
047      
048      public final void add(AppException ex){
049        fErrorMessages.add(ex);
050      }
051      
052      public boolean isEmpty(){
053        return fErrorMessages.isEmpty();
054      }
055      
056      public final boolean isNotEmpty(){
057        return !fErrorMessages.isEmpty();
058      }
059      
060      public final List<AppResponseMessage> getMessages(){
061        return fErrorMessages.getMessages();
062      }
063      
064      /** Intended for debugging only.  */
065      @Override public String toString(){
066        return fErrorMessages.toString();
067      }
068      
069      // PRIVATE 
070      
071      /**
072       List of error messages attached to this exception.
073       <P>Implementation Note :
074       This class is a wrapper of MessageListImpl, and simply forwards
075       related method calls to this field. This avoids code repetition.
076      */
077      private MessageList fErrorMessages = new MessageListImpl();
078    }