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.5 2009/08/31 19:16:35 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 Module module;
45      private final Set authors = new HashSet();
46  
47      /**
48       * Creates a VersionedFile object.
49       * 
50       * @param name The full name of the file
51       * @param directory the directory where the file resides
52       */
53      public VersionedFile(final String name, final Directory directory) {
54          this.filename = name;
55          this.directory = directory;
56          if (directory != null) {
57              directory.addFile(this);
58          }
59      }
60  
61      /**
62       * Returns a list of authors that have commited at least one revision of the file.
63       * @return a list of authors
64       */
65      public Set getAuthors() {
66          return authors;
67      }
68  
69      /**
70       * Returns the full filename.
71       * @return the full filename
72       */
73      public String getFilenameWithPath() {
74          return filename;
75      }
76  
77      /**
78       * Returns the filename without path.
79       * @return the filename without path
80       */
81      public String getFilename() {
82          final int lastDelim = this.filename.lastIndexOf("/");
83          return this.filename.substring(lastDelim + 1, this.filename.length());
84      }
85  
86      /**
87       * Returns the file's <tt>Directory</tt>.
88       * @return the file's <tt>Directory</tt>
89       */
90      public Directory getDirectory() {
91          return directory;
92      }
93  
94      /**
95       * Gets the latest revision of this file.
96       * @return the latest revision of this file
97       */
98      public Revision getLatestRevision() {
99          return (Revision) this.revisions.last();
100     }
101 
102     /**
103      * Gets the earliest revision of this file.
104      * @return the earliest revision of this file
105      */
106     public Revision getInitialRevision() {
107         return (Revision) this.revisions.first();
108     }
109 
110     /**
111      * Returns the list of {@link Revision}s of this file,
112      * sorted from earliest to most recent.
113      * @return a <tt>SortedSet</tt> of {@link Revision}s
114      */
115     public SortedSet getRevisions() {
116         return this.revisions;
117     }
118 
119     /**
120      * Returns the current number of lines for this file. Binary files
121      * and deleted files are assumed to have 0 lines.
122      * @return the current number of lines for this file
123      */
124     public int getCurrentLinesOfCode() {
125         return getLatestRevision().getLines();
126     }
127 
128     /**
129      * Returns <code>true</code> if the latest revision of this file was
130      * a deletion.
131      * @return <code>true</code> if this file is deleted
132      */
133     public boolean isDead() {
134         return getLatestRevision().isDead();
135     }
136 
137     /**
138      * Returns true, if <code>author</code> worked on this file.
139      * @param author The <code>Author</code> to search for
140      * @return <code>true</code>, if the author is listed in one of
141      * this file's revisions
142      */
143     public boolean hasAuthor(final Author author) {
144         return authors.contains(author);
145     }
146 
147     /**
148      * Returns the revision which was replaced by the revision given as
149      * argument. Returns <tt>null</tt> if the given revision is the initial
150      * revision of this file.
151      * @param revision a revision of this file
152      * @return this revision's predecessor
153      */
154     public Revision getPreviousRevision(final Revision revision) {
155         if (!revisions.contains(revision)) {
156             throw new IllegalArgumentException("revision not containted in file");
157         }
158         final SortedSet headSet = revisions.headSet(revision);
159         if (headSet.isEmpty()) {
160             return null;
161         }
162         return (Revision) headSet.last();
163     }
164 
165     /**
166      * {@inheritDoc}
167      */
168     public String toString() {
169         return getFilenameWithPath() + " (" + revisions.size() + " revisions)";
170     }
171 
172     /**
173      * Compares this file to another one, based on filename.
174      * @see java.lang.Comparable#compareTo(java.lang.Object)
175      */
176     public int compareTo(final Object other) {
177         return filename.compareTo(((VersionedFile) other).filename);
178     }
179 
180     public boolean equals(final Object rhs) {
181         if (rhs == null) {
182             return false;
183         }
184         if (!(rhs instanceof VersionedFile)) {
185             return false;
186         }
187         final VersionedFile that = (VersionedFile) rhs;
188 
189         final boolean eq = filename.equals(that.filename);
190 
191         return eq;
192     }
193 
194     public int hashCode() {
195         return filename.hashCode();
196     }
197 
198     /**
199      * Adds an initial revision to the file. An initial revision is either
200      * the first revision of the file, or a re-add after the file was
201      * deleted.
202      * @param revisionNumber the revision number, for example "1.1"
203      * @param author the login from which the change was committed
204      * @param date the time when the change was committed
205      * @param comment the commit message
206      * @param lines the number of lines of the new file
207      */
208     public Revision addInitialRevision(final String revisionNumber, final Author author, final Date date, final String comment, final int lines,
209             final SortedSet symbolicNames) {
210         final Revision result = new Revision(this, revisionNumber, Revision.TYPE_CREATION, author, date, comment, lines, lines, 0, symbolicNames);
211         addRevision(result);
212         return result;
213     }
214 
215     /**
216      * Adds a change revision to the file.
217      * @param revisionNumber the revision number, for example "1.1"
218      * @param author the login from which the change was committed
219      * @param date the time when the change was committed
220      * @param comment the commit message
221      * @param lines the number of lines in the file after the change
222      * @param linesDelta the change in the number of lines
223      * @param replacedLines number of lines that were removed and replaced by others
224      */
225     public Revision addChangeRevision(final String revisionNumber, final Author author, final Date date, final String comment, final int lines,
226             final int linesDelta, final int replacedLines, final SortedSet symbolicNames) {
227         final Revision result = new Revision(this, revisionNumber, Revision.TYPE_CHANGE, author, date, comment, lines, linesDelta, replacedLines, symbolicNames);
228         addRevision(result);
229         return result;
230     }
231 
232     /**
233      * Adds a deletion revision to the file.
234      * @param revisionNumber the revision number, for example "1.1"
235      * @param author the login from which the change was committed
236      * @param date the time when the change was committed
237      * @param comment the commit message
238      * @param lines the number of lines in the file before it was deleted
239      */
240     public Revision addDeletionRevision(final String revisionNumber, final Author author, final Date date, final String comment, final int lines,
241             final SortedSet symbolicNames) {
242         final Revision result = new Revision(this, revisionNumber, Revision.TYPE_DELETION, author, date, comment, 0, -lines, 0, symbolicNames);
243         addRevision(result);
244         return result;
245     }
246 
247     /**
248      * Adds a "begin of log" revision to the file. This kind of revision
249      * only marks the beginning of the log timespan if the file was
250      * already present in the repository at this time. It is not an actual
251      * revision committed by an author.
252      * @param date the begin of the log
253      * @param lines the number of lines in the file at that time
254      */
255     public Revision addBeginOfLogRevision(final Date date, final int lines, final SortedSet symbolicNames) {
256         final Revision result = new Revision(this, "0.0", Revision.TYPE_BEGIN_OF_LOG, null, date, null, lines, 0, 0, symbolicNames);
257         addRevision(result);
258         return result;
259     }
260 
261     private void addRevision(final Revision revision) {
262         revisions.add(revision);
263         if (revision.getAuthor() != null) {
264             authors.add(revision.getAuthor());
265         }
266     }
267 
268     public Module getModule() {
269         return module;
270     }
271 
272     public void setModule(Module module) {
273         this.module = module;
274     }
275 }