1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.statcvs.model;
21
22 import java.util.Date;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.SortedMap;
26 import java.util.SortedSet;
27 import java.util.TreeMap;
28 import java.util.TreeSet;
29
30 import net.sf.statcvs.Messages;
31 import net.sf.statcvs.util.FilePatternMatcher;
32 import net.sf.statcvs.util.ModuleUtil;
33
34 /**
35 * Represents a CVS Repository and provides access to the {@link VersionedFile}s,
36 * {@link Directory}s, {@link Revision}s and {@link Author}s recorded
37 * in the repository's history.
38 *
39 * TODO: Rename class to Repository, getCurrentLOC to getCurrentLines, getAuthors to getLogins
40 * TODO: Change getCommits to SortedSet
41 *
42 * @author Manuel Schulze
43 * @author Tammo van Lessen
44 * @author Richard Cyganiak <richard@cyganiak.de>
45 * @version $Id: Repository.java,v 1.5 2009/08/31 19:16:35 benoitx Exp $
46 */
47 public class Repository {
48 private final SortedSet files = new TreeSet();
49 private final SortedSet authors = new TreeSet();
50 private final SortedSet revisions = new TreeSet();
51 private final SortedMap modules = new TreeMap();
52 private Directory root = null;
53 private Date firstDate = null;
54 private Date lastDate = null;
55 private List commits;
56 private SortedSet symbolicNames = new TreeSet();
57 private final SymbolicName head = new SymbolicName("@");
58
59 /**
60 * Adds one file to the repository.
61 * @param file the file
62 */
63 public void addFile(final VersionedFile file) {
64 files.add(file);
65 final Iterator it = file.getRevisions().iterator();
66 while (it.hasNext()) {
67 final Revision revision = (Revision) it.next();
68 revisions.add(revision);
69 if (revision.getAuthor() != null) {
70 authors.add(revision.getAuthor());
71 }
72 adjustStartAndEndDate(revision.getDate());
73 }
74 if (root == null) {
75 initRoot();
76 }
77 if (!file.isDead()) {
78 this.head.addRevision(file.getLatestRevision());
79 }
80
81 if (ModuleUtil.modulesPresent()) {
82 addToModule(file);
83 }
84 }
85
86 private void addToModule(final VersionedFile file) {
87 final List moduleIds = ModuleUtil.getConfigModules();
88 final Iterator mod = moduleIds.iterator();
89 String modName = null;
90 while (mod.hasNext() && modName == null) {
91 final String moduleId = (String) mod.next();
92 final String pattern = ModuleUtil.getConfigModuleRegexp(moduleId);
93 final String name = ModuleUtil.getConfigModuleName(moduleId);
94
95 final FilePatternMatcher fpm = new FilePatternMatcher(pattern);
96
97 if (fpm.matches(file.getFilenameWithPath())) {
98 modName = name;
99 }
100 }
101
102 if (modName == null) {
103 modName = Messages.getString("PIE_MODSIZE_OTHER");
104 }
105
106 Module module = (Module) modules.get(modName);
107 if (module == null) {
108 module = new Module(modName);
109 modules.put(modName, module);
110 }
111 module.addFile(file);
112 file.setModule(module);
113 }
114
115 /**
116 * Sets the list of commits. <em>This method exists only because
117 * of stupid design. This method may only be called by stupid
118 * designers.</em>
119 * TODO: Fix this ugly hack!
120 * @param commits the list of commits
121 */
122 public void setCommits(final List commits) {
123 this.commits = commits;
124 }
125
126 /**
127 * Returns a <tt>List</tt> of all {@link Commit}s.
128 *
129 * @return all commits
130 */
131 public List getCommits() {
132 return commits;
133 }
134
135 /**
136 * Returns the latest {@link java.util.Date} when there
137 * were changes on the repository.
138 *
139 * @return The latest Date
140 */
141 public Date getLastDate() {
142 return lastDate;
143 }
144
145 /**
146 * Returns the first {@link java.util.Date} when there
147 * were changes on the repository.
148 *
149 * @return The first Date
150 */
151 public Date getFirstDate() {
152 return firstDate;
153 }
154
155 /**
156 * returns the current line count of the repository
157 * @return the current line count of the repository
158 */
159 public int getCurrentLOC() {
160 int result = 0;
161 final Iterator it = files.iterator();
162 while (it.hasNext()) {
163 final VersionedFile file = (VersionedFile) it.next();
164 result += file.getCurrentLinesOfCode();
165 }
166 return result;
167 }
168
169 /**
170 * Returns a list of all {@link VersionedFile}s, ordered by full name
171 * @return a list of all {@link VersionedFile}s
172 */
173 public SortedSet getFiles() {
174 return files;
175 }
176
177 /**
178 * Returns <tt>true</tt> if the repository contains no files.
179 * @return <tt>true</tt> if the repository is empty
180 */
181 public boolean isEmpty() {
182 return (files.isEmpty());
183 }
184
185 /**
186 * Returns a <tt>SortedSet</tt> of {@link Revision}s
187 * in the repository, sorted from oldest to most recent.
188 *
189 * @return all revisions in the repository.
190 */
191 public SortedSet getRevisions() {
192 return revisions;
193 }
194
195 /**
196 * Returns a <tt>SortedSet</tt> of all {@link Directory} objects
197 * in the repository, ordered in tree order
198 * @return a collection of <tt>Directory</tt> objects
199 */
200 public SortedSet getDirectories() {
201 return getRoot().getSubdirectoriesRecursive();
202 }
203
204 /**
205 * Returns the repository's root directory, or <tt>null</tt> if the
206 * directory contains no files.
207 * @return the root directory
208 */
209 public Directory getRoot() {
210 return root;
211 }
212
213 /**
214 * Sets the list of symbolic names contained in this Repository.
215 * @param symbolicNames
216 */
217 public void setSymbolicNames(final SortedSet symbolicNames) {
218 this.symbolicNames = symbolicNames;
219 }
220
221 /**
222 * Returns a list of {@link SymbolicName}s,
223 * ordered from latest to oldest.
224 */
225 public SortedSet getSymbolicNames() {
226 return symbolicNames;
227 }
228
229 /**
230 * A special symbolic name that contains the latest revision of every file.
231 */
232 public SymbolicName getHead() {
233 return this.head;
234 }
235
236 /**
237 * {@inheritDoc}
238 */
239 public String toString() {
240 final StringBuffer result = new StringBuffer();
241 final Iterator it = files.iterator();
242 VersionedFile cf = null;
243 while (it.hasNext()) {
244 cf = (VersionedFile) it.next();
245 result.append(cf.toString()).append("\n");
246 }
247 return result.toString();
248 }
249
250 /**
251 * Returns a <tt>SortedSet</tt> of all {@link Author}s who have
252 * committed to the repository, sorted by name.
253 * @return a <tt>SortedSet</tt> of <tt>Author</tt>s
254 */
255 public SortedSet getAuthors() {
256 return authors;
257 }
258
259 private void initRoot() {
260 if (files.isEmpty()) {
261 return;
262 }
263 final VersionedFile file = (VersionedFile) files.first();
264 Directory dir = file.getDirectory();
265 while (!dir.isRoot()) {
266 dir = dir.getParent();
267 }
268 root = dir;
269 }
270
271 private void adjustStartAndEndDate(final Date revisionDate) {
272 if (revisionDate == null) {
273 return;
274 }
275 if (firstDate == null || firstDate.compareTo(revisionDate) > 0) {
276 firstDate = revisionDate;
277 }
278 if (lastDate == null || lastDate.compareTo(revisionDate) < 0) {
279 lastDate = revisionDate;
280 }
281 }
282
283 public SortedMap getModules() {
284 return modules;
285 }
286 }