View Javadoc

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 }