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 }