001    package hirondelle.web4jtools.metrics.lines;
002    
003    import hirondelle.web4j.action.ResponsePage;
004    import hirondelle.web4j.request.RequestParameter;
005    import hirondelle.web4j.request.RequestParser;
006    import hirondelle.web4j.util.Util;
007    import hirondelle.web4jtools.metrics.base.FileInfo;
008    import hirondelle.web4jtools.metrics.base.MetricsAction;
009    
010    import java.util.Collections;
011    import java.util.Comparator;
012    import java.util.List;
013    
014    /**
015    * Display number of lines of source code, grouped by file extension. 
016    */
017    public final class LinesAction extends MetricsAction {
018    
019      /** Full constructor. */
020      public LinesAction(RequestParser aRequestParser){
021        super(FORWARD, aRequestParser);
022      }
023    
024      /** List the number of lines of source code, per file extension.  Default sort by total lines.*/
025      protected void calculateMetric()  {
026        LinesCounter linesCounter = getLinesCounter();
027        List<LineStat> stats = linesCounter.getStats();
028        sort(stats);
029        addToRequest("stats", stats);
030        addToRequest("totalLines", linesCounter.getTotalLines());
031        addToRequest("totalFiles", linesCounter.getTotalFiles());
032      }
033    
034      /** Column to sort by. See the <tt>sortLinks.tag</tt> file. */
035      public static final RequestParameter SORT_ON = RequestParameter.withRegexCheck("SortOn", "(Extension|AvgLines|NumFiles|TotalLines)");
036      /** Ascending or descending order. See the <tt>sortLinks.tag</tt> file. */
037      public static final RequestParameter ORDER = RequestParameter.withRegexCheck("Order", "(ASC|DESC)");
038      
039      // PRIVATE //
040      private static final ResponsePage FORWARD = new ResponsePage("Lines By File Extension", "view.jsp", LinesAction.class);
041      
042      private LinesCounter getLinesCounter(){
043        LinesCounter counter = new LinesCounter();
044        for(FileInfo fileInfo: fFileList){
045          if ( fileInfo.isSourceFile() ) {
046            counter.add(fileInfo);
047          }
048        }
049        return counter;    
050      }
051    
052      private void sort(List<LineStat> aStats){
053        String sortOn = getParamUnsafe(SORT_ON);
054        String order = getParamUnsafe(ORDER);
055        Collections.sort(aStats, getComparator(sortOn));
056        if( "DESC".equals(order) || ! Util.textHasContent(order)) {
057          Collections.reverse(aStats);
058        }
059      }
060      
061      private Comparator<LineStat> getComparator(String aSortOn){
062        Comparator<LineStat> result = null;
063        if( "Extension".equals(aSortOn)  ) {
064          result = new Comparator<LineStat>() {
065            public int compare(LineStat aThis, LineStat aThat) {
066              return aThis.getExtension().compareTo(aThat.getExtension());
067            };
068          };
069        }
070        else if ( "AvgLines".equals(aSortOn) ) {
071          result = new Comparator<LineStat>() {
072            public int compare(LineStat aThis, LineStat aThat) {
073              return aThis.getAverageLinesPerFile().compareTo(aThat.getAverageLinesPerFile());
074            };
075          };
076          
077        }
078        else if ( "NumFiles".equals(aSortOn) ) {
079          result = new Comparator<LineStat>() {
080            public int compare(LineStat aThis, LineStat aThat) {
081              return aThis.getNumFiles().compareTo(aThat.getNumFiles());
082            };
083          };
084          
085        }
086        //default sorting by total lines
087        else if ( "TotalLines".equals(aSortOn) || ! Util.textHasContent(aSortOn) ) {
088          result = new Comparator<LineStat>() {
089            public int compare(LineStat aThis, LineStat aThat) {
090              return aThis.getNumLines().compareTo(aThat.getNumLines());
091            };
092          };
093        }
094        else {
095          throw new AssertionError("Unknown sort column : " + Util.quote(aSortOn));
096        }
097        return result;
098      }
099    }