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  import net.sf.statcvs.util.StringUtils;
22  
23  /**
24   * @author anja
25   * @author Richard Cyganiak (richard@cyganiak.de)
26   * @version $Id: DeveloperPageMaker.java,v 1.15 2009/03/13 23:04:28 benoitx Exp $
27   */
28  public class DeveloperPageMaker {
29      private final static int RECENT_COMMITS_LENGTH = 20;
30      private final static NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance();
31  
32      static {
33          PERCENT_FORMAT.setMinimumFractionDigits(1);
34          PERCENT_FORMAT.setMaximumFractionDigits(1);
35      }
36  
37      public static String getURL(final Author developer) {
38          return getFilename(developer) + ".html";
39      }
40  
41      private static String getFilename(final Author developer) {
42          return "user_" + HTML.escapeAuthorName(developer.getName());
43      }
44  
45      private final ReportConfig config;
46      private final Author developer;
47      private final Repository repository;
48  
49      public DeveloperPageMaker(final ReportConfig config, final Author developer) {
50          this.config = config;
51          this.developer = developer;
52          this.repository = config.getRepository();
53      }
54  
55      public Page toFile() {
56          final ChartImage hourChart = new HourBarChartMaker("activity_time", this.config, this.developer.getRevisions(), Messages
57                  .getString("ACTIVITY_TIME_FOR_AUTHOR_TITLE")
58                  + " " + this.developer.getRealName(), "activity_time_" + HTML.escapeAuthorName(this.developer.getName()) + ".png").toFile();
59          final ChartImage weekdayChart = new WeekdayBarChartMaker("activity_day", this.config, this.developer.getRevisions(), Messages
60                  .getString("ACTIVITY_DAY_FOR_AUTHOR_TITLE")
61                  + " " + this.developer.getRealName(), "activity_day_" + HTML.escapeAuthorName(this.developer.getName()) + ".png").toFile();
62          final ChartImage codeDistributionChart = new CodeDistributionChartMaker(this.config, this.developer).toFile();
63  
64          String title;
65          if (this.config.isDeveloper(this.developer)) {
66              title = this.config.getProjectName() + " Developers: " + this.developer.getRealName();
67          } else {
68              title = "Non-developer Login: " + this.developer.getRealName();
69          }
70          final Page page = this.config.createPage(getFilename(this.developer), this.developer.getRealName(), title);
71          page.addAttribute("Login name", this.developer.getName());
72          if (this.developer.getRealName() != null && !this.developer.getRealName().equals(this.developer.getName())) {
73              page.addAttribute("Real name", this.developer.getRealName());
74          }
75          if (StringUtils.isNotEmpty(this.developer.getTwitterUserName())) {
76              page.addRawAttribute("Twitter", "@<a href=\"http://twitter.com/" + this.developer.getTwitterUserName() + "\">"
77                      + this.developer.getTwitterUserName() + "</a>");
78          }
79          if (StringUtils.isNotEmpty(this.developer.getEmail())) {
80              page.addRawAttribute("Email", "<a href=\"mailto:" + this.developer.getEmail() + "\">" + this.developer.getEmail() + "</a>");
81          }
82          if (StringUtils.isNotEmpty(this.developer.getHomePageUrl())) {
83              page.addRawAttribute("Home Page", "<a href=\"" + this.developer.getHomePageUrl() + "\">" + this.developer.getHomePageUrl() + "</a>");
84          }
85          if (StringUtils.isNotEmpty(this.developer.getImageUrl())) {
86              page.addRawAttribute("Image", "<img src=\"" + this.developer.getImageUrl() + "\" alt=\"" + this.developer.getRealName() + "\"/>");
87          }
88          page.addAttribute("Total Commits", getNumberAndPercentage(this.developer.getRevisions().size(), this.repository.getRevisions().size()));
89          page.addAttribute("Lines of Code", getNumberAndPercentage(countContributedLines(this.developer.getRevisions()), countContributedLines(this.repository
90                  .getRevisions())));
91          page.addAttribute("Most Recent Commit", ((Revision) this.developer.getRevisions().last()).getDate());
92          page.addSection(Messages.getString("ACTIVITY_TITLE"));
93          page.add(hourChart);
94          page.add(weekdayChart);
95  
96          if (StringUtils.isNotEmpty(this.developer.getTwitterUserName()) && this.developer.isTwitterIncludeHtml()) {
97              page.addSection("Twitter");
98              page.addRawContent("<div id=\"twitter_div\">");
99              page.addRawContent("<ul id=\"twitter_update_list\"/>");
100             page.addRawContent("<a href=\"http://twitter.com/" + developer.getTwitterUserName()
101                     + "\" id=\"twitter-link\" style=\"display:block;text-align:right;\">follow me on Twitter</a>");
102             page.addRawContent("</div>");
103             page.addRawContent("<script type=\"text/javascript\" src=\"http://twitter.com/javascripts/blogger.js\"></script>");
104             page.addRawContent("<script type=\"text/javascript\" src=\"http://twitter.com/statuses/user_timeline/" + developer.getTwitterUserName()
105                     + ".json?callback=twitterCallback2&amp;count=5\"></script>");
106         }
107         if (StringUtils.isNotEmpty(this.developer.getTwitterUserId()) && this.developer.isTwitterIncludeFlash()) {
108             page.addSection("Twitter");
109             page
110                     .addRawContent("<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,124,0\" width=\"550\" height=\"350\" id=\"TwitterWidget\" align=\"middle\">");
111             page.addRawContent("<param name=\"allowScriptAccess\" value=\"sameDomain\" />");
112             page.addRawContent("<param name=\"allowFullScreen\" value=\"false\" />");
113             page.addRawContent("<param name=\"movie\" value=\"http://static.twitter.com/flash/widgets/profile/TwitterWidget.swf\" />");
114             page.addRawContent("<param name=\"quality\" value=\"high\" />");
115             page.addRawContent("<param name=\"bgcolor\" value=\"#000000\" />");
116             page.addRawContent("<param name=\"FlashVars\" value=\"userID=" + developer.getTwitterUserId()
117                     + "&amp;styleURL=http://static.twitter.com/flash/widgets/profile/velvetica.xml\"/>");
118             page
119                     .addRawContent("<embed src=\"http://static.twitter.com/flash/widgets/profile/TwitterWidget.swf\" quality=\"high\" bgcolor=\"#000000\" width=\"550\" height=\"350\" name=\"TwitterWidget\" align=\"middle\" allowScriptAccess=\"sameDomain\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" FlashVars=\"userID="
120                             + developer.getTwitterUserId() + "&amp;styleURL=http://static.twitter.com/flash/widgets/profile/velvetica.xml\"/></object>");
121         }
122 
123         page.addSection("Activity in Directories");
124         page.add(new DirectoriesForAuthorTableReport(this.config, this.developer));
125         if (codeDistributionChart != null) {
126             page.add(codeDistributionChart);
127         }
128         page.addSection(Messages.getString("MOST_RECENT_COMMITS"));
129         page.addRawContent(new CommitListFormatter(this.config, getRecentCommits(), Collections.EMPTY_LIST, RECENT_COMMITS_LENGTH, false).render());
130         return page;
131     }
132 
133     private List getRecentCommits() {
134         final List results = new ArrayList();
135         final Iterator it = this.repository.getCommits().iterator();
136         while (it.hasNext()) {
137             final Commit commit = (Commit) it.next();
138             if (this.developer.equals(commit.getAuthor())) {
139                 results.add(commit);
140             }
141         }
142         return results;
143     }
144 
145     private int countContributedLines(final Collection revisions) {
146         int result = 0;
147         final Iterator it = revisions.iterator();
148         while (it.hasNext()) {
149             final Revision element = (Revision) it.next();
150             result += element.getNewLines();
151         }
152         return result;
153     }
154 
155     /**
156      * returns the percentage of a given total count and the count.
157      * This will work, because division by zero is not a problem with doubles:
158      * you get NaN (and the formatter will format that too).
159      * @author Jan Dockx
160      * @param value
161      * @param total
162      * @return String percentage string
163      */
164     private String getNumberAndPercentage(final int value, final int total) {
165         final double factor = (double) value / (double) total;
166         return value + " (" + PERCENT_FORMAT.format(factor) + ")";
167     }
168 }