001    package hirondelle.web4jtools.metrics.lines;
002    
003    import hirondelle.web4j.security.SafeText;
004    import hirondelle.web4jtools.metrics.base.FileInfo;
005    import hirondelle.web4j.util.Util;
006    import hirondelle.web4j.model.ModelUtil;
007    
008    /**
009    * Model Object for line stats for a single file extension.
010    * <P>This class is mutable.  
011    */
012    public final class LineStat {
013      
014      /** Full constructor. */
015      public LineStat(SafeText aExtension) {
016        fExtension = aExtension;
017      }
018      
019      /** Return the file extension for this stat. */
020      public SafeText getExtension(){
021        return fExtension;
022      }
023      
024      /** Return the number of lines for this extension.  */
025      public Long getNumLines(){
026        return fNumLines;  
027      }
028      
029      /** Return the number of files for this extension.  */
030      public Long getNumFiles(){
031        return fNumFiles;
032      }
033      
034      /** Return (num lines / num files). */
035      public Long getAverageLinesPerFile(){
036        return fNumLines / fNumFiles; //integer division will truncate remainder
037      }
038      
039      /** Add a new file to this stat, if its extension matches this object.  */
040      public void add(FileInfo aFileInfo){
041        if ( ! aFileInfo.getExtension().equals(fExtension) ) {
042          throw new AssertionError("FileInfo object has extension " + Util.quote(aFileInfo.getExtension()) + ", but expecting only extension " + Util.quote(getExtension()));
043        }
044        fNumFiles = fNumFiles + 1;
045        fNumLines = fNumLines + aFileInfo.getNumLines();
046      }
047      
048      public String toString(){
049        return ModelUtil.toStringFor(this);
050      }
051      
052      public boolean equals(Object aThat){
053        Boolean result = ModelUtil.quickEquals(this, aThat);
054        if( result == null){
055          LineStat that = (LineStat)aThat;
056          result = ModelUtil.equalsFor(this.getSignificantFields(), that.getSignificantFields());
057        }
058        return result;
059      }
060      
061      public int hashCode(){
062        //no cache - mutable
063        return ModelUtil.hashCodeFor(getSignificantFields());
064      }
065      
066      // PRIVATE //
067      private SafeText fExtension;
068      private long fNumLines;
069      private long fNumFiles;
070      
071      private Object[] getSignificantFields(){
072        return new Object[]{fExtension, fNumFiles, fNumLines};
073      }
074    }