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.Iterator;
23 import java.util.SortedSet;
24 import java.util.TreeSet;
25
26 /**
27 * Represents a directory in the {@link Repository Repository}, a
28 * container for {@link VersionedFile}s and sub<tt>Directory</tt>s.
29 * A new root directory is created by {@link #createRoot}.
30 * The {@link #createSubdirectory} method creates new subdirectories.
31 *
32 * TODO: Rename getCurrentLOC to getCurrentLines or getCurrentLineCount
33 *
34 * @author Richard Cyganiak <richard@cyganiak.de>
35 * @version $Id: Directory.java,v 1.11 2008/04/02 11:22:16 benoitx Exp $
36 */
37 public abstract class Directory implements Comparable {
38 private final SortedSet files = new TreeSet();
39 private final SortedSet directories = new TreeSet();
40
41 /**
42 * Factory method for creating a new root directory.
43 * @return a new root directory
44 */
45 public static Directory createRoot() {
46 return new DirectoryRoot();
47 }
48
49 /**
50 * Factory method for creating a new subdirectory.
51 * @param name the subdirectory's name
52 * @return the subdirectory instance
53 */
54 public Directory createSubdirectory(final String name) {
55 final Directory result = new DirectoryImpl(this, name);
56 directories.add(result);
57 return result;
58 }
59
60 /**
61 * Returns the directory's name without full path or any slashes,
62 * for example "src".
63 * @return the directory's name
64 */
65 public abstract String getName();
66
67 /**
68 * Returns the directory's full path with trailing slash,
69 * for example "src/net/sf/statcvs/".
70 * @return the directory's path
71 */
72 public abstract String getPath();
73
74 /**
75 * Returns the directory's parent directory or <tt>null</tt> if it is the root
76 * @return the directory's parent.
77 */
78 public abstract Directory getParent();
79
80 /**
81 * Returns <tt>true</tt> if this is the root of the directory tree.
82 * @return <tt>true</tt> if this is the root of the directory tree
83 */
84 public abstract boolean isRoot();
85
86 /**
87 * Returns the level of this directory in the direcotry tree.
88 * The root has level 0, its subdirectories have level 1, and so forth.
89 * @return the level of this directory in the directory tree
90 */
91 public abstract int getDepth();
92
93 /**
94 * Returns all {@link VersionedFile} objects in this directory, ordered
95 * by filename. Files in subdirectories are not included.
96 * @return the files in this directory
97 */
98 public SortedSet getFiles() {
99 return files;
100 }
101
102 /**
103 * Returns all {@link Revision}s to files in
104 * this directory, in order from oldest to most recent.
105 * @return list of <tt>Revision</tt>s for this directory
106 */
107 public SortedSet getRevisions() {
108 final SortedSet result = new TreeSet();
109 final Iterator iterator = files.iterator();
110 while (iterator.hasNext()) {
111 final VersionedFile file = (VersionedFile) iterator.next();
112 result.addAll(file.getRevisions());
113 }
114 return result;
115 }
116
117 /**
118 * Returns a <tt>SortedSet</tt> of all immediate subdirectories,
119 * ordered by name.
120 * @return <tt>SortedSet</tt> of {@link Directory} objects
121 */
122 public SortedSet getSubdirectories() {
123 return directories;
124 }
125
126 /**
127 * Returns a list of all subdirectories, including their subdirectories
128 * and this directory itself. The list is preordered, beginning with this
129 * directory itself.
130 * @return <tt>SortedSet</tt> of {@link Directory} objects
131 */
132 public SortedSet getSubdirectoriesRecursive() {
133 final SortedSet result = new TreeSet();
134 result.add(this);
135 final Iterator it = directories.iterator();
136 while (it.hasNext()) {
137 final Directory dir = (Directory) it.next();
138 result.addAll(dir.getSubdirectoriesRecursive());
139 }
140 return result;
141 }
142
143 /**
144 * Returns the number of lines in this directory. The returned number
145 * will be for the current revisions of all files.
146 * @return lines in this directory
147 */
148 public int getCurrentLOC() {
149 int result = 0;
150 final Iterator it = files.iterator();
151 while (it.hasNext()) {
152 final VersionedFile file = (VersionedFile) it.next();
153 result += file.getCurrentLinesOfCode();
154 }
155 return result;
156 }
157
158 /**
159 * Returns the number of files in this directory. Deleted files are not
160 * counted.
161 * @return number of files in this directory
162 */
163 public int getCurrentFileCount() {
164 int result = 0;
165 final Iterator it = files.iterator();
166 while (it.hasNext()) {
167 final VersionedFile file = (VersionedFile) it.next();
168 if (!file.isDead()) {
169 result++;
170 }
171 }
172 return result;
173 }
174
175 /**
176 * Returns <code>true</code> if all files in this directory and its
177 * subdirectories are deleted, or if it doesn't have any files and
178 * subdirectories at all.
179 * @return <code>true</code> if the directory is currently empty
180 */
181 public boolean isEmpty() {
182 Iterator it = files.iterator();
183 while (it.hasNext()) {
184 final VersionedFile file = (VersionedFile) it.next();
185 if (!file.isDead()) {
186 return false;
187 }
188 }
189 it = directories.iterator();
190 while (it.hasNext()) {
191 final Directory subdir = (Directory) it.next();
192 if (!subdir.isEmpty()) {
193 return false;
194 }
195 }
196 return true;
197 }
198
199 /**
200 * Compares this directory to another one, based on their full names.
201 * @see java.lang.Comparable#compareTo(java.lang.Object)
202 */
203 public int compareTo(final Object o) {
204 return getPath().compareTo(((Directory) o).getPath());
205 }
206
207 /**
208 * Adds a file to this directory.
209 * @param file a file in this directory
210 */
211 void addFile(final VersionedFile file) {
212 files.add(file);
213 }
214 }