001    package hirondelle.web4jtools.logview.parsedview;
002    
003    import hirondelle.web4j.model.ModelUtil;
004    import hirondelle.web4j.security.SafeText;
005    import java.util.Date;
006    import java.util.logging.Level;
007    import hirondelle.web4j.util.Util;
008    
009    /** 
010    * Model Object for a parsed Logger Record.
011    * 
012    * <P>A parsed logger record can be filtered and sorted according to various criteria, 
013    * making it easier to find needed information.
014    * 
015    * <P>This class is mutable.
016    */
017    public final class LoggerRecord {
018    
019      /**
020      * Full constructor.
021      *  
022      * @param aLevel Logging level (required).
023      * @param aDate Date of the logging message (required).
024      * @param aLogger Logger/package name (required).
025      * @param aMethod name of the method emitting the message (optional).
026      * @param aMessage Text of the logging message (required).
027      */
028      public LoggerRecord(
029       String aLevel, 
030       Date aDate, 
031       String aLogger, 
032       String aMethod,
033       String aMessage
034      ) {
035        fLevel = Util.textHasContent(aLevel) ? Level.parse(aLevel) : null;
036        fDate = aDate.getTime(); //defensive form
037        fLogger = new SafeText(aLogger);
038        fMethod = new SafeText(aMethod);
039        fMessage = new SafeText(aMessage);
040      }
041    
042      /**
043      * Alternate constructor.
044      * 
045      * Useful for building a partial log from the first line of a record. 
046      */
047      public LoggerRecord(Date aDate, String aLogger, String aMethod) {
048        fDate = aDate.getTime();
049        fLogger = new SafeText(aLogger);
050        fMethod = new SafeText(aMethod);
051      }
052      
053      /** Set the level for this record. */
054      public void addLevel(String aLevel) {
055        fLevel = Util.textHasContent(aLevel) ? Level.parse(aLevel) : null;
056      }
057      
058      /** Set the log message for this record. */
059      public void addMessage(String aMessage) {
060        fMessage = new SafeText(aMessage);
061      }
062      
063      public Level getLevel() { return fLevel; }  
064      public Date getDate() { return new Date(fDate); }
065      public SafeText getLogger() { return fLogger; }  
066      public SafeText getMethod() { return fMethod; }
067      public SafeText getMessage() { return fMessage; }
068      
069      @Override public String toString(){
070        return ModelUtil.toStringFor(this);
071      }
072      
073      @Override public boolean equals(Object aThat){
074        Boolean result = ModelUtil.quickEquals(this, aThat);
075        if ( result == null ) {
076          LoggerRecord that = (LoggerRecord)aThat;
077          result = ModelUtil.equalsFor(this.getSignificantFields(), that.getSignificantFields());
078        }
079        return result;
080      }
081      
082      @Override public int hashCode(){
083        //cannot cache - mutable
084        return ModelUtil.hashCodeFor(getSignificantFields());
085      }
086    
087      // PRIVATE 
088      private Level fLevel;
089      private final Long fDate;
090      private final SafeText fLogger;
091      private final SafeText fMethod;
092      private SafeText fMessage;
093    
094      private Object[] getSignificantFields(){
095        return new Object[] {fLevel, fDate, fLogger, fMethod, fMessage};
096      }
097    }