~ubuntu-branches/ubuntu/saucy/statsvn/saucy

« back to all changes in this revision

Viewing changes to src/net/sf/statsvn/output/RepoMapPageMaker.java

  • Committer: Bazaar Package Importer
  • Author(s): Vincent Fourmond
  • Date: 2010-03-16 21:32:06 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100316213206-1rublguvacx6gd0k
Tags: 0.7.0.dfsg-1
* New upstream release (closes: #572613)
* Switch to source format 3.0 (quilt)
* Drop build-dependency on dpatch, now unneeded
* Now conforms to standards 3.8.4
* Switch to a dependency on default-jdk for building
* Now depends on libsvnkit-java
* Manual page updates.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 StatSVN - SVN Subversion statistics generation
3
 
 Copyright (C) 2006 Benoit Xhenseval
4
 
 http://www.statsvn.org
5
 
 
6
 
 This library is free software; you can redistribute it and/or
7
 
 modify it under the terms of the GNU Lesser General Public
8
 
 License as published by the Free Software Foundation; either
9
 
 version 2.1 of the License, or (at your option) any later version.
10
 
 
11
 
 This library is distributed in the hope that it will be useful,
12
 
 but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
 Lesser General Public License for more details.
15
 
 
16
 
 You should have received a copy of the GNU Lesser General Public
17
 
 License along with this library; if not, write to the Free Software
18
 
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 
20
 
 */
21
 
package net.sf.statsvn.output;
22
 
 
23
 
import java.io.BufferedWriter;
24
 
import java.io.File;
25
 
import java.io.FileWriter;
26
 
import java.io.IOException;
27
 
import java.io.InputStream;
28
 
import java.io.Writer;
29
 
import java.util.Calendar;
30
 
import java.util.Date;
31
 
import java.util.Iterator;
32
 
import java.util.SortedSet;
33
 
 
34
 
import net.sf.statcvs.Messages;
35
 
import net.sf.statcvs.model.Directory;
36
 
import net.sf.statcvs.model.Revision;
37
 
import net.sf.statcvs.model.VersionedFile;
38
 
import net.sf.statcvs.output.ConfigurationOptions;
39
 
import net.sf.statcvs.output.ReportConfig;
40
 
import net.sf.statcvs.pages.HTML;
41
 
import net.sf.statcvs.pages.NavigationNode;
42
 
import net.sf.statcvs.pages.Page;
43
 
import net.sf.statcvs.util.FileUtils;
44
 
 
45
 
/**
46
 
 * New report that Repo Map, a jtreemap-based report (applet) that shows the
47
 
 * entire source tree in a hierarchical manner, the size of each box is related
48
 
 * to LOC and the colour to the changes over the last 30 days (red -loc, green
49
 
 * +loc).
50
 
 *
51
 
 * @author Benoit Xhenseval (www.objectlab.co.uk)
52
 
 * @see http://jtreemap.sourceforge.net for more about JTreeMap.
53
 
 */
54
 
public class RepoMapPageMaker {
55
 
        private static final int DAYS_FROM_LAST_DATE = 30;
56
 
 
57
 
        private static final String WEB_FILE_PATH = "web-files/";
58
 
 
59
 
        private static final String REPO_FILE = "repomap-data.txt";
60
 
 
61
 
        private final Date deadline;
62
 
        
63
 
        private final Date currentDate;
64
 
 
65
 
        private final ReportConfig config;
66
 
 
67
 
        private int indent = 0;
68
 
 
69
 
        /**
70
 
         * @see net.sf.statcvs.output.HTMLPage#HTMLPage(Repository)
71
 
         */
72
 
        public RepoMapPageMaker(final ReportConfig config) {
73
 
                final Calendar cal = Calendar.getInstance();
74
 
                if (config !=null && config.getRepository() != null && config.getRepository().getLastDate()!=null) {
75
 
                        cal.setTime(config.getRepository().getLastDate());
76
 
                }
77
 
                currentDate = cal.getTime();
78
 
                cal.add(Calendar.DATE, -DAYS_FROM_LAST_DATE);
79
 
                deadline = cal.getTime();
80
 
                this.config = config;
81
 
        }
82
 
 
83
 
        public NavigationNode toFile() {
84
 
                final Page page = this.config.createPage("repomap", Messages.getString("REPOMAP_TITLE"), Messages.getString("REPOMAP_TITLE"));
85
 
                page.addRawAttribute(Messages.getString("REPOMAP_START_DATE"), HTML.getDate(deadline));
86
 
                page.addRawAttribute(Messages.getString("REPOMAP_END_DATE"), HTML.getDate(currentDate));
87
 
 
88
 
                page.addRawContent("<p>" + Messages.getString("REPOMAP_DESCRIPTION") + "</p>");
89
 
                page.addRawContent("<p>" + getApplet() + "</p>");
90
 
                page.addRawContent("<p><small>This page uses <a href=\"http://jtreemap.sourceforge.net\">JTreeMap</a>.</small></p>");
91
 
                buildXmlForJTreeMap();
92
 
 
93
 
                return page;
94
 
        }
95
 
 
96
 
        private String getApplet() {
97
 
                return "<applet archive=\"./" + Messages.getString("JTREEMAP_JAR") + "\" code=\"net.sf.jtreemap.swing.example.JTreeMapAppletExample\""
98
 
                        + " width=\"940\" height=\"600\"><param name=\"dataFile\" value=\"" + REPO_FILE + "\"/>" + "<param name=\"viewTree\" value=\"true\"/>"
99
 
                        + "<param name=\"showWeight\" value=\"true\"/>" + "<param name=\"valuePrefix\" value=\"Change:\"/>"
100
 
                        + "<param name=\"weightPrefix\" value=\"LOC:\"/>" + "<param name=\"dataFileType\" value=\"xml\"/>"
101
 
                        + "<param name=\"colorProvider\" value=\"HSBLog\"/>" + "</applet>";
102
 
        }
103
 
 
104
 
        private void buildXmlForJTreeMap() {
105
 
                BufferedWriter out = null;
106
 
                try {
107
 
                        copyJar(Messages.getString("JTREEMAP_JAR"));
108
 
                        out = new BufferedWriter(new FileWriter(ConfigurationOptions.getOutputDir() + REPO_FILE));
109
 
                        out.write("<?xml version='1.0' encoding='ISO-8859-1'?>\n");
110
 
                        // out.append("<!DOCTYPE root SYSTEM \"TreeMap.dtd\" >\n");
111
 
                        out.write("<root>\n");
112
 
                        final Iterator it = config.getRepository().getDirectories().iterator();
113
 
                        if (it.hasNext()) {
114
 
                                final Directory dir = (Directory) it.next();
115
 
                                doDirectory(out, dir);
116
 
                        }
117
 
                        out.write("</root>");
118
 
                } catch (final IOException e) {
119
 
                        e.printStackTrace();
120
 
                } finally {
121
 
                        if (out != null) {
122
 
                                try {
123
 
                                        out.close();
124
 
                                } catch (final IOException e) {
125
 
                                        SvnConfigurationOptions.getTaskLogger().error(e.toString());
126
 
                                }
127
 
                        }
128
 
                }
129
 
        }
130
 
 
131
 
        private void copyJar(final String jtreemapJar) throws IOException {
132
 
                InputStream stream = null;
133
 
                try {
134
 
                        stream = RepoMapPageMaker.class.getResourceAsStream(WEB_FILE_PATH + jtreemapJar);
135
 
                        if (stream != null) {
136
 
                                FileUtils.copyFile(stream, new File(ConfigurationOptions.getOutputDir() + jtreemapJar));
137
 
                        } else {
138
 
                                throw new IOException("The stream to " + (WEB_FILE_PATH + jtreemapJar) + " failed, is it copied in the jar?");
139
 
                        }
140
 
                } finally {
141
 
                        if (stream != null) {
142
 
                                stream.close();
143
 
                        }
144
 
                }
145
 
        }
146
 
 
147
 
        private void addSpaces(final int count, final BufferedWriter out) throws IOException {
148
 
                out.write(getSpaces(count));
149
 
        }
150
 
 
151
 
        private String getSpaces(final int count) {
152
 
                final StringBuffer result = new StringBuffer();
153
 
                for (int i = 0; i < count; i++) {
154
 
                        result.append("  ");
155
 
                }
156
 
                return result.toString();
157
 
        }
158
 
 
159
 
        private void doDirectory(final BufferedWriter out, final Directory dir) throws IOException {
160
 
                indent++;
161
 
                SvnConfigurationOptions.getTaskLogger().log("Directory:" + getSpaces(indent) + dir.getName());
162
 
 
163
 
                if (dir.isEmpty()) {
164
 
                        indent--;
165
 
                        return;
166
 
                }
167
 
 
168
 
                final SortedSet set = dir.getSubdirectories();
169
 
                final SortedSet files = dir.getFiles();
170
 
                final String name = dir.isRoot() ? Messages.getString("NAVIGATION_ROOT") : dir.getName();
171
 
                boolean addedBranch = false;
172
 
                if (indent > 1 && set != null && !set.isEmpty()) {
173
 
                        out.write("\n");
174
 
                        addSpaces(indent, out);
175
 
                        out.write("<branch>\n");
176
 
                        addSpaces(indent + 2, out);
177
 
                        labelTag(out, name);
178
 
                        addedBranch = true;
179
 
                } else if (indent == 1) {
180
 
                        addSpaces(indent, out);
181
 
                        labelTag(out, name);
182
 
                }
183
 
                if (set != null) {
184
 
                        for (final Iterator it2 = set.iterator(); it2.hasNext();) {
185
 
                                doDirectory(out, (Directory) it2.next());
186
 
                        }
187
 
                }
188
 
                addedBranch = handleEachFileInDir(out, files, name, addedBranch);
189
 
                if (addedBranch) {
190
 
                        addSpaces(indent, out);
191
 
                        out.write("</branch>\n");
192
 
                }
193
 
                indent--;
194
 
        }
195
 
 
196
 
        private boolean handleEachFileInDir(final BufferedWriter out, final SortedSet files, final String name, boolean addedBranch) throws IOException {
197
 
                if (files != null && !files.isEmpty()) {
198
 
                        for (final Iterator file = files.iterator(); file.hasNext();) {
199
 
                                final VersionedFile vfile = (VersionedFile) file.next();
200
 
 
201
 
                                int loc = vfile.getCurrentLinesOfCode();
202
 
 
203
 
                                SvnConfigurationOptions.getTaskLogger().log("File:" + vfile.getFilename() + " LOC:" + loc);
204
 
 
205
 
                                int delta = calculateTotalDelta(vfile);
206
 
                                if (loc == 0) {
207
 
                                        loc = Math.abs(delta);
208
 
                                }
209
 
                                if (loc == 0) {
210
 
                                        continue;
211
 
                                }
212
 
                                if (!addedBranch) {
213
 
                                        out.write("\n");
214
 
                                        addSpaces(indent, out);
215
 
                                        out.write("<branch>\n");
216
 
                                        addSpaces(indent + 2, out);
217
 
                                        labelTag(out, name);
218
 
                                        out.write("\n");
219
 
                                        addedBranch = true;
220
 
                                }
221
 
                                addSpaces(indent + 2, out);
222
 
                                out.write("<leaf>");
223
 
                                labelTag(out, vfile.getFilename());
224
 
                                tag(out, "weight", String.valueOf(loc));
225
 
                                final double percentage = ((double) delta) / (double) loc * 100.0;
226
 
                                tag(out, "value", String.valueOf(percentage));
227
 
                                out.write("</leaf>\n");
228
 
                                SvnConfigurationOptions.getTaskLogger().log("===========>>> LOC=" + loc + " totalDelta=" + delta + " Delta%=" + percentage);
229
 
                        }
230
 
                }
231
 
                return addedBranch;
232
 
        }
233
 
 
234
 
        private int calculateTotalDelta(final VersionedFile vfile) {
235
 
                int delta = 0;
236
 
                final SortedSet revisions = vfile.getRevisions();
237
 
                // take all deltas for the last 30 days.
238
 
                for (final Iterator rev = revisions.iterator(); rev.hasNext();) {
239
 
                        final Revision revision = (Revision) rev.next();
240
 
 
241
 
                        SvnConfigurationOptions.getTaskLogger().log(
242
 
                                "Revision " + revision.getDate() + " file:" + vfile.getFilename() + " Dead:" + vfile.isDead() + " LOC:" + revision.getLines() + " delta:"
243
 
                                        + revision.getLinesDelta());
244
 
 
245
 
                        if (deadline.before(revision.getDate())) {
246
 
                                delta += revision.getLinesDelta();
247
 
 
248
 
                                SvnConfigurationOptions.getTaskLogger().log(
249
 
                                        "Revision " + revision.getRevisionNumber() + " Delta:" + revision.getLinesDelta() + " totalDelta:" + delta + " LOC:"
250
 
                                                + revision.getLines() + " Dead:" + revision.isDead());
251
 
                        }
252
 
                }
253
 
                return delta;
254
 
        }
255
 
 
256
 
        private void labelTag(final Writer result, final String name) throws IOException {
257
 
                if (name == null || name.length() == 0) {
258
 
                        tag(result, "label", "[root]");
259
 
                } else {
260
 
                        tag(result, "label", name);
261
 
                }
262
 
        }
263
 
 
264
 
        private void tag(final Writer result, final String tagName, final String value) throws IOException {
265
 
                result.write("<");
266
 
                result.write(tagName);
267
 
                result.write(">");
268
 
                result.write(value);
269
 
                result.write("</");
270
 
                result.write(tagName);
271
 
                result.write(">");
272
 
        }
273
 
}