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