View Javadoc

1   package net.sf.statcvs.pages;
2   
3   import java.text.NumberFormat;
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.Collections;
7   import java.util.Iterator;
8   import java.util.List;
9   
10  import net.sf.statcvs.Messages;
11  import net.sf.statcvs.charts.ChartImage;
12  import net.sf.statcvs.charts.DirectoryPieChartMaker.CodeDistributionChartMaker;
13  import net.sf.statcvs.charts.TimeBarChartMaker.HourBarChartMaker;
14  import net.sf.statcvs.charts.TimeBarChartMaker.WeekdayBarChartMaker;
15  import net.sf.statcvs.model.Author;
16  import net.sf.statcvs.model.Commit;
17  import net.sf.statcvs.model.Repository;
18  import net.sf.statcvs.model.Revision;
19  import net.sf.statcvs.output.ReportConfig;
20  import net.sf.statcvs.reports.DirectoriesForAuthorTableReport;
21  
22  /**
23   * @author anja
24   * @author Richard Cyganiak (richard@cyganiak.de)
25   * @version $Id: DeveloperPageMaker.java,v 1.11 2008/04/02 11:22:14 benoitx Exp $
26   */
27  public class DeveloperPageMaker {
28      private final static int RECENT_COMMITS_LENGTH = 20;
29      private final static NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance();
30  
31      static {
32          PERCENT_FORMAT.setMinimumFractionDigits(1);
33          PERCENT_FORMAT.setMaximumFractionDigits(1);
34      }
35  
36      public static String getURL(final Author developer) {
37          return getFilename(developer) + ".html";
38      }
39  
40      private static String getFilename(final Author developer) {
41          return "user_" + HTML.escapeAuthorName(developer.getName());
42      }
43  
44      private final ReportConfig config;
45      private final Author developer;
46      private final Repository repository;
47  
48      public DeveloperPageMaker(final ReportConfig config, final Author developer) {
49          this.config = config;
50          this.developer = developer;
51          this.repository = config.getRepository();
52      }
53  
54      public Page toFile() {
55          final ChartImage hourChart = new HourBarChartMaker(this.config, this.developer.getRevisions(), Messages.getString("ACTIVITY_TIME_FOR_AUTHOR_TITLE")
56                  + " " + this.developer.getRealName(), "activity_time_" + HTML.escapeAuthorName(this.developer.getName()) + ".png").toFile();
57          final ChartImage weekdayChart = new WeekdayBarChartMaker(this.config, this.developer.getRevisions(), Messages
58                  .getString("ACTIVITY_DAY_FOR_AUTHOR_TITLE")
59                  + " " + this.developer.getRealName(), "activity_day_" + HTML.escapeAuthorName(this.developer.getName()) + ".png").toFile();
60          final ChartImage codeDistributionChart = new CodeDistributionChartMaker(this.config, this.developer).toFile();
61  
62          String title;
63          if (this.config.isDeveloper(this.developer)) {
64              title = this.config.getProjectName() + " Developers: " + this.developer.getRealName();
65          } else {
66              title = "Non-developer Login: " + this.developer.getRealName();
67          }
68          final Page page = this.config.createPage(getFilename(this.developer), this.developer.getRealName(), title);
69          page.addAttribute("Login name", this.developer.getName());
70          if (this.developer.getRealName() != null && !this.developer.getRealName().equals(this.developer.getName())) {
71              page.addAttribute("Real name", this.developer.getRealName());
72          }
73          if (this.developer.getEmail() != null && this.developer.getEmail().length() > 0) {
74              page.addRawAttribute("Email", "<a href=\"mailto:" + this.developer.getEmail() + "\">" + this.developer.getEmail() + "</a>");
75          }
76          if (this.developer.getHomePageUrl() != null && this.developer.getHomePageUrl().length() > 0) {
77              page.addRawAttribute("Home Page", "<a href=\"" + this.developer.getHomePageUrl() + "\">" + this.developer.getHomePageUrl() + "</a>");
78          }
79          if (this.developer.getImageUrl() != null && this.developer.getImageUrl().length() > 0) {
80              page.addRawAttribute("Image", "<img src=\"" + this.developer.getImageUrl() + "\" alt=\"" + this.developer.getRealName() + "\"/>");
81          }
82          page.addAttribute("Total Commits", getNumberAndPercentage(this.developer.getRevisions().size(), this.repository.getRevisions().size()));
83          page.addAttribute("Lines of Code", getNumberAndPercentage(countContributedLines(this.developer.getRevisions()), countContributedLines(this.repository
84                  .getRevisions())));
85          page.addAttribute("Most Recent Commit", ((Revision) this.developer.getRevisions().last()).getDate());
86          page.addSection(Messages.getString("ACTIVITY_TITLE"));
87          page.add(hourChart);
88          page.add(weekdayChart);
89          page.addSection("Activity in Directories");
90          page.add(new DirectoriesForAuthorTableReport(this.config, this.developer));
91          if (codeDistributionChart != null) {
92              page.add(codeDistributionChart);
93          }
94          page.addSection(Messages.getString("MOST_RECENT_COMMITS"));
95          page.addRawContent(new CommitListFormatter(this.config, getRecentCommits(), Collections.EMPTY_LIST, RECENT_COMMITS_LENGTH, false).render());
96          return page;
97      }
98  
99      private List getRecentCommits() {
100         final List results = new ArrayList();
101         final Iterator it = this.repository.getCommits().iterator();
102         while (it.hasNext()) {
103             final Commit commit = (Commit) it.next();
104             if (this.developer.equals(commit.getAuthor())) {
105                 results.add(commit);
106             }
107         }
108         return results;
109     }
110 
111     private int countContributedLines(final Collection revisions) {
112         int result = 0;
113         final Iterator it = revisions.iterator();
114         while (it.hasNext()) {
115             final Revision element = (Revision) it.next();
116             result += element.getNewLines();
117         }
118         return result;
119     }
120 
121     /**
122      * returns the percentage of a given total count and the count.
123      * This will work, because division by zero is not a problem with doubles:
124      * you get NaN (and the formatter will format that too).
125      * @author Jan Dockx
126      * @param value
127      * @param total
128      * @return String percentage string
129      */
130     private String getNumberAndPercentage(final int value, final int total) {
131         final double factor = (double) value / (double) total;
132         return value + " (" + PERCENT_FORMAT.format(factor) + ")";
133     }
134 }