1 package net.sf.statcvs.pages.xml;
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.model.Commit;
12 import net.sf.statcvs.model.Revision;
13 import net.sf.statcvs.model.SymbolicName;
14 import net.sf.statcvs.renderer.FileCollectionFormatter;
15
16 import org.jdom.CDATA;
17 import org.jdom.Element;
18
19 /**
20 * This is a mere copy of the CommitListFormatter class with dfew minor changes done
21 * Class for formatting a list of commits as XML.
22 *
23 * @author Anja Jentzsch
24 * @author Richard Cyganiak (richard@cyganiak.de)
25 * @version $Id: CommitListXml.java,v 1.4 2008/04/02 11:52:02 benoitx Exp $
26 */
27 public class CommitListXml {
28 private final List commits;
29 private final List tags;
30 private final HashMap commitHashMap = new HashMap();
31
32 /**
33 * Creates a new instance for the list of commits.
34 * @param commits A list of {@link Commit} objects
35 */
36 public CommitListXml(final List commits, final List tags, final boolean withPermalinks) {
37 this(commits, tags, Integer.MAX_VALUE, withPermalinks);
38 }
39
40 /**
41 * Creates a new instance for the list of commits.
42 * @param commits A list of {@link Commit} objects
43 * @param max maximum number of commits for the log; if there
44 * are more, only the most recent will be used
45 */
46 public CommitListXml(final List commit, final List tags, final int max, final boolean withPermalinks) {
47 this.commits = new ArrayList(commit);
48 this.tags = tags;
49 Collections.reverse(this.commits);
50 }
51
52 public Element renderCommitList(final List commitList) {
53 if (commitList.isEmpty()) {
54 return null;
55 }
56 int id = commitList.size();
57 final Element lg = new Element(XmlTags.TAG_COMMIT_LIST);
58 final Iterator commitIt = commitList.iterator();
59 Commit nextCommit = commitIt.hasNext() ? (Commit) commitIt.next() : null;
60 final Iterator tagIt = this.tags.iterator();
61 SymbolicName nextTag = tagIt.hasNext() ? (SymbolicName) tagIt.next() : null;
62 while (nextCommit != null) {
63 Element log = null;
64 if (nextTag == null || nextCommit.getDate().getTime() > nextTag.getDate().getTime()) {
65 log = renderCommit(nextCommit, id);
66 nextCommit = commitIt.hasNext() ? (Commit) commitIt.next() : null;
67 id--;
68 } else {
69 nextTag = tagIt.hasNext() ? (SymbolicName) tagIt.next() : null;
70 }
71 lg.addContent(log);
72 }
73 return lg;
74 }
75
76 private Element renderCommit(final Commit commit, final int id) {
77 final Element cmt = new Element(XmlTags.TAG_COMMIT);
78
79 cmt.setAttribute("date", getDate(commit));
80 cmt.setAttribute("author", getAuthor(commit));
81 cmt.setAttribute("loc_change", getLinesOfCode(commit));
82 final String revision = getRevisionNumber(commit);
83 if (revision != null) {
84 cmt.setAttribute("revision", revision);
85 }
86 final Element comment = new Element(XmlTags.TAG_COMMENT);
87 final CDATA theActualComment = new CDATA(commit.getComment());
88 comment.addContent(theActualComment);
89 cmt.addContent(comment);
90 cmt.addContent(getAffectedFiles(commit));
91
92 return cmt;
93 }
94
95 private String getRevisionNumber(final Commit commit) {
96 final Set rev = new HashSet();
97 for (final Iterator it = commit.getRevisions().iterator(); it.hasNext();) {
98 rev.add(((Revision) it.next()).getRevisionNumber());
99 }
100 if (rev.size() == 1) {
101 return (String) rev.iterator().next();
102 } else {
103 return null;
104 }
105 }
106
107 private String getDate(final Commit commit) {
108 return XML.getDateAndTime(commit.getDate());
109 }
110
111 private String getAuthor(final Commit commit) {
112 return XML.getAuthorLink(commit.getAuthor());
113 }
114
115 private String getLinesOfCode(final Commit commit) {
116 final Iterator it = commit.getRevisions().iterator();
117 int locSum = 0;
118 while (it.hasNext()) {
119 final Revision each = (Revision) it.next();
120 locSum += each.getNewLines();
121 saveRevision(each);
122 }
123 return Integer.toString(locSum);
124 }
125
126 private void saveRevision(final Revision revision) {
127 commitHashMap.put(revision.getFile().getFilenameWithPath(), revision);
128 }
129
130 private Element getAffectedFiles(final Commit commit) {
131 final Element result = new Element(XmlTags.TAG_FILES_AFFECTED);
132 final FileCollectionFormatter formatter = new FileCollectionFormatter(commit.getAffectedFiles());
133 final Iterator it = formatter.getDirectories().iterator();
134 while (it.hasNext()) {
135 final String directory = (String) it.next();
136 final Iterator files = formatter.getFiles(directory).iterator();
137 final StringBuffer fileList = new StringBuffer();
138 while (files.hasNext()) {
139 final Element File = new Element(XmlTags.TAG_FILE);
140 if (fileList.length() > 0) {
141 fileList.append(",\n");
142 }
143 final String file = (String) files.next();
144 final Element path = new Element(XmlTags.TAG_PATH).setText(directory + file);
145 File.addContent(path);
146 final Revision revision = (Revision) commitHashMap.get(directory + file);
147 if (revision.isInitialRevision()) {
148 final int linesAdded = revision.getLines();
149 File.setAttribute("action", "new");
150 if (linesAdded > 0) {
151 File.addContent(new Element(XmlTags.TAG_LOC_ADDED).setText(Integer.toString(linesAdded)));
152 }
153 } else if (revision.isDead()) {
154 File.setAttribute("action", "deleted");
155 } else {
156 final int delta = revision.getLinesDelta();
157 final int linesAdded = revision.getReplacedLines() + ((delta > 0) ? delta : 0);
158 final int linesRemoved = revision.getReplacedLines() - ((delta < 0) ? delta : 0);
159 if (linesAdded > 0) {
160 File.setAttribute("action", "changed");
161 File.addContent(new Element(XmlTags.TAG_LOC_ADDED).setText(Integer.toString(linesAdded)));
162 if (linesRemoved > 0) {
163 File.addContent(new Element(XmlTags.TAG_LOC_REMOVED).setText(Integer.toString(linesRemoved)));
164 }
165 } else if (linesRemoved > 0) {
166 File.setAttribute("action", "changed");
167 File.addContent(new Element(XmlTags.TAG_LOC_ADDED).setText("0"));
168 File.addContent(new Element(XmlTags.TAG_LOC_REMOVED).setText(Integer.toString(linesRemoved)));
169 } else {
170
171 File.setAttribute("action", "binary file or keyword subst change");
172 }
173 }
174 result.addContent(File);
175 }
176 }
177 return result;
178 }
179 }