1 /* 2 StatCvs - CVS statistics generation 3 Copyright (C) 2002 Lukasz Pekacki <lukasz@pekacki.de> 4 http://statcvs.sf.net/ 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 package net.sf.statcvs.model; 21 22 import java.util.Date; 23 import java.util.HashSet; 24 import java.util.Set; 25 import java.util.SortedSet; 26 import java.util.TreeSet; 27 28 /** 29 * Represents one versioned file in the {@link Repository Repository}, 30 * including its name, {@link Directory} and {@link Revision} list. 31 * Revisions can be created using the <tt>addXXXRevision</tt> factory 32 * methods. Revisions can be created in any order. 33 * 34 * TODO: Rename class to something like VersionedFile, getCurrentLinesOfCode() to getCurrentLines(), maybe getFilenameXXX, isDead() to isDeleted() 35 * 36 * @author Manuel Schulze 37 * @author Richard Cyganiak <richard@cyganiak.de> 38 * @version $Id: VersionedFile.java,v 1.2 2008/04/02 11:22:16 benoitx Exp $ 39 */ 40 public class VersionedFile implements Comparable { 41 private final String filename; 42 private final SortedSet revisions = new TreeSet(); 43 private final Directory directory; 44 private final Set authors = new HashSet(); 45 46 /** 47 * Creates a VersionedFile object. 48 * 49 * @param name The full name of the file 50 * @param directory the directory where the file resides 51 */ 52 public VersionedFile(final String name, final Directory directory) { 53 this.filename = name; 54 this.directory = directory; 55 if (directory != null) { 56 directory.addFile(this); 57 } 58 } 59 60 /** 61 * Returns a list of authors that have commited at least one revision of the file. 62 * @return a list of authors 63 */ 64 public Set getAuthors() { 65 return authors; 66 } 67 68 /** 69 * Returns the full filename. 70 * @return the full filename 71 */ 72 public String getFilenameWithPath() { 73 return filename; 74 } 75 76 /** 77 * Returns the filename without path. 78 * @return the filename without path 79 */ 80 public String getFilename() { 81 final int lastDelim = this.filename.lastIndexOf("/"); 82 return this.filename.substring(lastDelim + 1, this.filename.length()); 83 } 84 85 /** 86 * Returns the file's <tt>Directory</tt>. 87 * @return the file's <tt>Directory</tt> 88 */ 89 public Directory getDirectory() { 90 return directory; 91 } 92 93 /** 94 * Gets the latest revision of this file. 95 * @return the latest revision of this file 96 */ 97 public Revision getLatestRevision() { 98 return (Revision) this.revisions.last(); 99 } 100 101 /** 102 * Gets the earliest revision of this file. 103 * @return the earliest revision of this file 104 */ 105 public Revision getInitialRevision() { 106 return (Revision) this.revisions.first(); 107 } 108 109 /** 110 * Returns the list of {@link Revision}s of this file, 111 * sorted from earliest to most recent. 112 * @return a <tt>SortedSet</tt> of {@link Revision}s 113 */ 114 public SortedSet getRevisions() { 115 return this.revisions; 116 } 117 118 /** 119 * Returns the current number of lines for this file. Binary files 120 * and deleted files are assumed to have 0 lines. 121 * @return the current number of lines for this file 122 */ 123 public int getCurrentLinesOfCode() { 124 return getLatestRevision().getLines(); 125 } 126 127 /** 128 * Returns <code>true</code> if the latest revision of this file was 129 * a deletion. 130 * @return <code>true</code> if this file is deleted 131 */ 132 public boolean isDead() { 133 return getLatestRevision().isDead(); 134 } 135 136 /** 137 * Returns true, if <code>author</code> worked on this file. 138 * @param author The <code>Author</code> to search for 139 * @return <code>true</code>, if the author is listed in one of 140 * this file's revisions 141 */ 142 public boolean hasAuthor(final Author author) { 143 return authors.contains(author); 144 } 145 146 /** 147 * Returns the revision which was replaced by the revision given as 148 * argument. Returns <tt>null</tt> if the given revision is the initial 149 * revision of this file. 150 * @param revision a revision of this file 151 * @return this revision's predecessor 152 */ 153 public Revision getPreviousRevision(final Revision revision) { 154 if (!revisions.contains(revision)) { 155 throw new IllegalArgumentException("revision not containted in file"); 156 } 157 final SortedSet headSet = revisions.headSet(revision); 158 if (headSet.isEmpty()) { 159 return null; 160 } 161 return (Revision) headSet.last(); 162 } 163 164 /** 165 * {@inheritDoc} 166 */ 167 public String toString() { 168 return getFilenameWithPath() + " (" + revisions.size() + " revisions)"; 169 } 170 171 /** 172 * Compares this file to another one, based on filename. 173 * @see java.lang.Comparable#compareTo(java.lang.Object) 174 */ 175 public int compareTo(final Object other) { 176 return filename.compareTo(((VersionedFile) other).filename); 177 } 178 179 /** 180 * Adds an initial revision to the file. An initial revision is either 181 * the first revision of the file, or a re-add after the file was 182 * deleted. 183 * @param revisionNumber the revision number, for example "1.1" 184 * @param author the login from which the change was committed 185 * @param date the time when the change was committed 186 * @param comment the commit message 187 * @param lines the number of lines of the new file 188 */ 189 public Revision addInitialRevision(final String revisionNumber, final Author author, final Date date, final String comment, final int lines, 190 final SortedSet symbolicNames) { 191 final Revision result = new Revision(this, revisionNumber, Revision.TYPE_CREATION, author, date, comment, lines, lines, 0, symbolicNames); 192 addRevision(result); 193 return result; 194 } 195 196 /** 197 * Adds a change revision to the file. 198 * @param revisionNumber the revision number, for example "1.1" 199 * @param author the login from which the change was committed 200 * @param date the time when the change was committed 201 * @param comment the commit message 202 * @param lines the number of lines in the file after the change 203 * @param linesDelta the change in the number of lines 204 * @param replacedLines number of lines that were removed and replaced by others 205 */ 206 public Revision addChangeRevision(final String revisionNumber, final Author author, final Date date, final String comment, final int lines, 207 final int linesDelta, final int replacedLines, final SortedSet symbolicNames) { 208 final Revision result = new Revision(this, revisionNumber, Revision.TYPE_CHANGE, author, date, comment, lines, linesDelta, replacedLines, symbolicNames); 209 addRevision(result); 210 return result; 211 } 212 213 /** 214 * Adds a deletion revision to the file. 215 * @param revisionNumber the revision number, for example "1.1" 216 * @param author the login from which the change was committed 217 * @param date the time when the change was committed 218 * @param comment the commit message 219 * @param lines the number of lines in the file before it was deleted 220 */ 221 public Revision addDeletionRevision(final String revisionNumber, final Author author, final Date date, final String comment, int lines, 222 final SortedSet symbolicNames) { 223 final Revision result = new Revision(this, revisionNumber, Revision.TYPE_DELETION, author, date, comment, 0, -lines, 0, symbolicNames); 224 addRevision(result); 225 return result; 226 } 227 228 /** 229 * Adds a "begin of log" revision to the file. This kind of revision 230 * only marks the beginning of the log timespan if the file was 231 * already present in the repository at this time. It is not an actual 232 * revision committed by an author. 233 * @param date the begin of the log 234 * @param lines the number of lines in the file at that time 235 */ 236 public Revision addBeginOfLogRevision(final Date date, final int lines, final SortedSet symbolicNames) { 237 final Revision result = new Revision(this, "0.0", Revision.TYPE_BEGIN_OF_LOG, null, date, null, lines, 0, 0, symbolicNames); 238 addRevision(result); 239 return result; 240 } 241 242 private void addRevision(final Revision revision) { 243 revisions.add(revision); 244 if (revision.getAuthor() != null) { 245 authors.add(revision.getAuthor()); 246 } 247 } 248 }