Coverage Report - net.sf.statcvs.pages.CommitListFormatter
 
Classes in this File Line Coverage Branch Coverage Complexity
CommitListFormatter
0%
0/131
0%
0/60
2.667
 
 1  
 package net.sf.statcvs.pages;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.Collections;
 5  
 import java.util.HashMap;
 6  
 import java.util.HashSet;
 7  
 import java.util.Iterator;
 8  
 import java.util.List;
 9  
 import java.util.Set;
 10  
 
 11  
 import net.sf.statcvs.Messages;
 12  
 import net.sf.statcvs.model.Commit;
 13  
 import net.sf.statcvs.model.Revision;
 14  
 import net.sf.statcvs.model.SymbolicName;
 15  
 import net.sf.statcvs.output.ReportConfig;
 16  
 import net.sf.statcvs.output.WebRepositoryIntegration;
 17  
 import net.sf.statcvs.renderer.FileCollectionFormatter;
 18  
 
 19  
 /**
 20  
  * Class for formatting a list of commits as HTML.
 21  
  *
 22  
  * @author Anja Jentzsch
 23  
  * @author Richard Cyganiak (richard@cyganiak.de)
 24  
  * @version $Id: CommitListFormatter.java,v 1.17 2009/08/22 10:30:42 benoitx Exp $
 25  
  */
 26  
 public class CommitListFormatter {
 27  
     private final ReportConfig config;
 28  
     private final List commits;
 29  
     private final List tags;
 30  
     private final int max;
 31  
     private final boolean withPermalinks;
 32  0
     private final HashMap commitHashMap = new HashMap();
 33  
 
 34  
     /**
 35  
      * Creates a new instance for the list of commits.
 36  
      * @param commits A list of {@link Commit} objects
 37  
      */
 38  
     public CommitListFormatter(final ReportConfig config, final List commits, final List tags, final boolean withPermalinks) {
 39  0
         this(config, commits, tags, Integer.MAX_VALUE, withPermalinks);
 40  0
     }
 41  
 
 42  
     /**
 43  
      * Creates a new instance for the list of commits.
 44  
      * @param commits A list of {@link Commit} objects
 45  
      * @param max maximum number of commits for the log; if there
 46  
      * are more, only the most recent will be used
 47  
      */
 48  0
     public CommitListFormatter(final ReportConfig config, final List commit, final List tags, final int max, final boolean withPermalinks) {
 49  0
         this.config = config;
 50  0
         this.commits = new ArrayList(commit);
 51  0
         this.tags = tags;
 52  0
         this.max = max;
 53  0
         this.withPermalinks = withPermalinks;
 54  0
         Collections.reverse(this.commits);
 55  0
     }
 56  
 
 57  
     /**
 58  
      * Returns HTML code for the commit log without splitting the list
 59  
      * into pages.
 60  
      *
 61  
      * @return HTML code for the commit log
 62  
      */
 63  
     public String render() {
 64  0
         if (this.commits.size() > this.max) {
 65  0
             final List recentCommits = this.commits.subList(0, this.max);
 66  0
             return renderCommitList(recentCommits) + "<p>(" + (this.commits.size() - this.max) + " " + Messages.getString("MORE_COMMITS") + ")</p>\n";
 67  
         }
 68  0
         return renderCommitList(this.commits);
 69  
     }
 70  
 
 71  
     private String renderCommitList(final List commitList) {
 72  0
         if (commitList.isEmpty()) {
 73  0
             return "<p>No commits</p>\n";
 74  
         }
 75  0
         int id = commitList.size();
 76  0
         final StringBuffer result = new StringBuffer("<dl class=\"commitlist\">\n");
 77  0
         final Iterator commitIt = commitList.iterator();
 78  0
         Commit nextCommit = commitIt.hasNext() ? (Commit) commitIt.next() : null;
 79  0
         final Iterator tagIt = this.tags.iterator();
 80  0
         SymbolicName nextTag = tagIt.hasNext() ? (SymbolicName) tagIt.next() : null;
 81  0
         while (nextCommit != null) {
 82  0
             if (nextTag == null || nextCommit.getDate().getTime() > nextTag.getDate().getTime()) {
 83  0
                 result.append(renderCommit(nextCommit, id));
 84  0
                 nextCommit = commitIt.hasNext() ? (Commit) commitIt.next() : null;
 85  0
                 id--;
 86  
             } else {
 87  0
                 renderTag(result, nextTag);
 88  0
                 nextTag = tagIt.hasNext() ? (SymbolicName) tagIt.next() : null;
 89  
             }
 90  
         }
 91  0
         result.append("</dl>\n\n");
 92  0
         return result.toString();
 93  
     }
 94  
 
 95  
     private void renderTag(final StringBuffer s, final SymbolicName tag) {
 96  0
         final String anchor = HTML.escape(CommitLogPageMaker.getAnchor(tag));
 97  0
         s.append("  <dt class=\"tag\"><a name=\"").append(anchor).append("\">\n");
 98  0
         s.append("    Repository Tag: ").append(HTML.escape(tag.getName())).append("</a>\n");
 99  0
         s.append("  </dt>\n");
 100  0
     }
 101  
 
 102  
     private String renderCommit(final Commit commit, final int id) {
 103  0
         final StringBuffer result = new StringBuffer();
 104  0
         result.append("  <dt><a name=\"" + id + "\"></a>\n");
 105  0
         result.append("    ").append(getAuthor(commit)).append("\n");
 106  0
         result.append("    ").append(getDate(commit)).append("\n");
 107  0
         if (this.withPermalinks) {
 108  0
             result.append("    ").append(getPermalink(id)).append("\n");
 109  
         }
 110  0
         final String revisionNumber = getRevisionNumber(commit);
 111  0
         if (revisionNumber != null) {
 112  0
             result.append("    ").append(revisionNumber).append("\n");
 113  
         }
 114  0
         result.append("  </dt>\n");
 115  0
         result.append("  <dd>\n");
 116  0
         result.append("    <p class=\"comment\">\n");
 117  0
         result.append(getComment(commit)).append("\n");
 118  0
         result.append("    </p>\n");
 119  0
         result.append("    <p class=\"commitdetails\"><strong>");
 120  0
         result.append(getLinesOfCode(commit)).append("</strong> ");
 121  0
         result.append("lines of code changed in ");
 122  0
         result.append(getAffectedFilesCount(commit));
 123  0
         result.append(":</p>\n");
 124  0
         result.append(getAffectedFiles(commit)).append("  </dd>\n\n");
 125  0
         return result.toString();
 126  
     }
 127  
 
 128  
     private String getPermalink(final int id) {
 129  0
         return "<a class=\"permalink\" title=\"Permalink to this commit\" href=\"#" + id + "\">#" + id + "</a>";
 130  
     }
 131  
 
 132  
     private String getRevisionNumber(final Commit commit) {
 133  0
         final Set rev = new HashSet();
 134  0
         for (final Iterator it = commit.getRevisions().iterator(); it.hasNext();) {
 135  0
             rev.add(((Revision) it.next()).getRevisionNumber());
 136  
         }
 137  0
         if (rev.size() == 1) {
 138  0
             return HTML.getRevisionNumber((String) rev.iterator().next());
 139  
         } else {
 140  0
             return null;
 141  
         }
 142  
     }
 143  
 
 144  
     private String getDate(final Commit commit) {
 145  0
         return HTML.getDateAndTime(commit.getDate());
 146  
     }
 147  
 
 148  
     private String getAuthor(final Commit commit) {
 149  0
         return HTML.getAuthorLink(commit.getAuthor());
 150  
     }
 151  
 
 152  
     private String getAffectedFilesCount(final Commit commit) {
 153  0
         return HTML.getAffectedFilesCount(commit.getRevisions());
 154  
     }
 155  
 
 156  
     private String getComment(final Commit commit) {
 157  0
         return this.config.getWebBugtracker().toHTMLWithLinks(commit.getComment());
 158  
     }
 159  
 
 160  
     private String getLinesOfCode(final Commit commit) {
 161  0
         final Iterator it = commit.getRevisions().iterator();
 162  0
         int locSum = 0;
 163  0
         while (it.hasNext()) {
 164  0
             final Revision each = (Revision) it.next();
 165  0
             locSum += each.getNewLines();
 166  0
             saveRevision(each);
 167  0
         }
 168  0
         return Integer.toString(locSum);
 169  
     }
 170  
 
 171  
     private void saveRevision(final Revision revision) {
 172  0
         commitHashMap.put(revision.getFile().getFilenameWithPath(), revision);
 173  0
     }
 174  
 
 175  
     private String getAffectedFiles(final Commit commit) {
 176  0
         final StringBuffer result = new StringBuffer("    <ul class=\"commitdetails\">\n");
 177  0
         final FileCollectionFormatter formatter = new FileCollectionFormatter(commit.getAffectedFiles());
 178  0
         final Iterator it = formatter.getDirectories().iterator();
 179  0
         while (it.hasNext()) {
 180  0
             result.append("      <li>\n");
 181  0
             final String directory = (String) it.next();
 182  0
             if (!directory.equals("")) {
 183  0
                 result.append("        <strong>").append(directory.substring(0, directory.length() - 1)).append("</strong>:\n");
 184  
             }
 185  0
             final Iterator files = formatter.getFiles(directory).iterator();
 186  0
             final StringBuffer fileList = new StringBuffer();
 187  0
             while (files.hasNext()) {
 188  0
                 if (fileList.length() > 0) {
 189  0
                     fileList.append(",\n");
 190  
                 }
 191  0
                 fileList.append("        ");
 192  0
                 final String file = (String) files.next();
 193  0
                 final Revision revision = (Revision) commitHashMap.get(directory + file);
 194  0
                 final WebRepositoryIntegration webRepository = this.config.getWebRepository();
 195  0
                 if (webRepository != null) {
 196  0
                     final Revision previous = revision.getPreviousRevision();
 197  
                     String url;
 198  0
                     if (previous == null || revision.isInitialRevision()) {
 199  0
                         url = webRepository.getFileViewUrl(revision);
 200  0
                     } else if (revision.isDead()) {
 201  0
                         url = webRepository.getFileViewUrl(previous);
 202  
                     } else {
 203  0
                         url = webRepository.getDiffUrl(previous, revision);
 204  
                     }
 205  0
                     fileList.append("<a href=\"").append(HTML.escapeUrl(url)).append("\" class=\"webrepository\">").append(HTML.escape(file)).append("</a>");
 206  0
                 } else {
 207  0
                     fileList.append(file);
 208  
                 }
 209  0
                 if (revision.isInitialRevision()) {
 210  0
                     final int linesAdded = revision.getLines();
 211  0
                     fileList.append("&#160;<span class=\"new\">(new");
 212  0
                     if (linesAdded > 0) {
 213  0
                         fileList.append("&#160;").append(linesAdded);
 214  
                     }
 215  0
                     fileList.append(")</span>");
 216  0
                 } else if (revision.isDead()) {
 217  0
                     fileList.append("&#160;<span class=\"del\">(del)</span>");
 218  
                 } else {
 219  0
                     final int delta = revision.getLinesDelta();
 220  0
                     final int linesAdded = revision.getReplacedLines() + ((delta > 0) ? delta : 0);
 221  0
                     final int linesRemoved = revision.getReplacedLines() - ((delta < 0) ? delta : 0);
 222  0
                     fileList.append("&#160;<span class=\"change\">(");
 223  0
                     if (linesAdded > 0) {
 224  0
                         fileList.append("+").append(linesAdded);
 225  0
                         if (linesRemoved > 0) {
 226  0
                             fileList.append("&#160;-").append(linesRemoved);
 227  
                         }
 228  0
                     } else if (linesRemoved > 0) {
 229  0
                         fileList.append("-").append(linesRemoved);
 230  
                     } else { // linesAdded == linesRemoved == 0
 231  
                         // should be binary file or keyword subst change
 232  0
                         fileList.append("changed");
 233  
                     }
 234  0
                     fileList.append(")</span>");
 235  
                 }
 236  0
             }
 237  0
             result.append(fileList.toString()).append("\n      </li>\n");
 238  0
         }
 239  0
         result.append("    </ul>\n");
 240  0
         return result.toString();
 241  
     }
 242  
 }