Mercurial > hg > digilib-old
annotate servlet/src/digilib/io/DocuDirCache.java @ 204:37a697fd8ec6
original-size working now - probably
| author | luginbue |
|---|---|
| date | Tue, 02 Mar 2004 13:43:39 +0100 |
| parents | bb4ed821d06e |
| children | f8c82fea551a |
| rev | line source |
|---|---|
| 176 | 1 /* |
| 2 * DocuDirCache.java | |
| 3 * | |
| 4 * Digital Image Library servlet components | |
| 5 * | |
| 6 * Copyright (C) 2003 Robert Casties (robcast@mail.berlios.de) | |
| 7 * | |
| 8 * This program is free software; you can redistribute it and/or modify it | |
| 9 * under the terms of the GNU General Public License as published by the Free | |
| 10 * Software Foundation; either version 2 of the License, or (at your option) | |
| 11 * any later version. | |
| 12 * | |
| 13 * Please read license.txt for the full details. A copy of the GPL may be found | |
| 14 * at http://www.gnu.org/copyleft/lgpl.html | |
| 15 * | |
| 16 * You should have received a copy of the GNU General Public License along with | |
| 17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
| 18 * Place, Suite 330, Boston, MA 02111-1307 USA | |
| 19 * | |
| 86 | 20 * Created on 03.03.2003 |
| 21 */ | |
| 22 | |
| 23 package digilib.io; | |
| 24 | |
| 25 import java.io.File; | |
| 91 | 26 import java.util.HashMap; |
| 159 | 27 import java.util.Iterator; |
| 28 import java.util.LinkedList; | |
| 29 import java.util.List; | |
| 86 | 30 |
| 181 | 31 import org.apache.log4j.Logger; |
| 32 | |
| 86 | 33 /** |
| 34 * @author casties | |
| 35 */ | |
| 91 | 36 public class DocuDirCache { |
| 86 | 37 |
| 181 | 38 /** general logger for this class */ |
| 39 protected Logger logger = Logger.getLogger(this.getClass()); | |
| 159 | 40 /** HashMap of directories */ |
| 176 | 41 protected HashMap map = null; |
| 159 | 42 /** names of base directories */ |
| 86 | 43 private String[] baseDirNames = null; |
| 159 | 44 /** array of allowed file classes (image/text) */ |
| 45 private int[] fileClasses = null; | |
| 46 /** number of files in the whole cache (approximate) */ | |
| 86 | 47 private long numFiles = 0; |
| 159 | 48 /** number of cache hits */ |
| 86 | 49 private long hits = 0; |
| 159 | 50 /** number of cache misses */ |
| 86 | 51 private long misses = 0; |
| 52 | |
| 176 | 53 /** |
| 54 * Constructor with array of base directory names and file classes. | |
| 55 * | |
| 56 * @param bd | |
| 57 * base directory names | |
| 159 | 58 */ |
| 59 public DocuDirCache(String[] bd, int[] fileClasses) { | |
| 60 baseDirNames = bd; | |
| 61 map = new HashMap(); | |
| 62 this.fileClasses = fileClasses; | |
| 63 } | |
| 176 | 64 /** |
| 65 * Constructor with array of base directory names. | |
| 66 * | |
| 67 * @param bd | |
| 68 * base directory names | |
| 86 | 69 */ |
| 70 public DocuDirCache(String[] bd) { | |
| 71 baseDirNames = bd; | |
| 91 | 72 map = new HashMap(); |
| 159 | 73 // default file class is CLASS_IMAGE |
| 74 fileClasses = new int[1]; | |
| 75 fileClasses[0] = FileOps.CLASS_IMAGE; | |
| 91 | 76 } |
| 77 | |
| 176 | 78 /** |
| 79 * The number of directories in the cache. | |
| 80 * | |
| 91 | 81 * @return |
| 82 */ | |
| 83 public int size() { | |
| 84 return (map != null) ? map.size() : 0; | |
| 86 | 85 } |
| 86 | |
| 176 | 87 /** |
| 88 * Add a DocuDirectory to the cache. | |
| 86 | 89 * |
| 90 * @param newdir | |
| 91 */ | |
| 92 public void put(DocuDirectory newdir) { | |
| 93 String s = newdir.getDirName(); | |
| 91 | 94 if (map.containsKey(s)) { |
| 197 | 95 logger.warn("Duplicate key in DocuDirCache.put -- ignoring!"); |
| 86 | 96 } else { |
| 91 | 97 map.put(s, newdir); |
| 86 | 98 numFiles += newdir.size(); |
| 99 } | |
| 100 } | |
| 101 | |
| 176 | 102 /** |
| 103 * Add a directory to the cache and check its parents. | |
| 151 | 104 * |
| 105 * @param newDir | |
| 106 */ | |
| 107 public void putDir(DocuDirectory newDir) { | |
| 108 put(newDir); | |
| 109 String parent = newDir.getParentDirName(); | |
| 110 if (parent != null) { | |
| 111 // check the parent in the cache | |
| 176 | 112 DocuDirectory pd = (DocuDirectory) map.get(parent); |
| 151 | 113 if (pd == null) { |
| 114 // the parent is unknown | |
| 115 pd = new DocuDirectory(parent, this); | |
| 116 putDir(pd); | |
| 117 } | |
| 118 newDir.setParent(pd); | |
| 119 } | |
| 120 } | |
| 121 | |
| 176 | 122 /** |
| 123 * Get a list with all children of a directory. | |
| 159 | 124 * |
| 176 | 125 * Returns a List of DocuDirectory's. Returns an empty List if the |
| 126 * directory has no children. If recurse is false then only direct children | |
| 127 * are returned. | |
| 159 | 128 * |
| 129 * @param dirname | |
| 176 | 130 * @param recurse |
| 131 * find all children and their children. | |
| 159 | 132 * @return |
| 133 */ | |
| 134 public List getChildren(String dirname, boolean recurse) { | |
| 135 List l = new LinkedList(); | |
| 176 | 136 for (Iterator i = map.keySet().iterator(); i.hasNext();) { |
| 137 DocuDirectory dd = (DocuDirectory) i.next(); | |
| 159 | 138 if (recurse) { |
| 139 if (dd.getDirName().startsWith(dirname)) { | |
| 140 l.add(dd); | |
| 141 } | |
| 142 } else { | |
| 143 if (dd.getParentDirName().equals(dirname)) { | |
| 144 l.add(dd); | |
| 145 } | |
| 146 } | |
| 147 } | |
| 148 return l; | |
| 149 } | |
| 150 | |
| 176 | 151 /** |
| 187 | 152 * Returns the DocuDirent with the pathname <code>fn</code> and the |
| 159 | 153 * index <code>in</code> and the class <code>fc</code>. |
| 91 | 154 * |
| 187 | 155 * If <code>fn</code> is a file then the corresponding DocuDirent is |
| 91 | 156 * returned and the index is ignored. |
| 157 * | |
| 176 | 158 * @param fn |
| 159 * digilib pathname | |
| 160 * @param in | |
| 161 * file index | |
| 162 * @return | |
| 91 | 163 */ |
| 159 | 164 public DocuDirent getFile(String fn, int in, int fc) { |
| 86 | 165 DocuDirectory dd; |
| 166 // file number is 1-based, vector index is 0-based | |
| 167 int n = in - 1; | |
| 168 // first, assume fn is a directory and look in the cache | |
| 91 | 169 dd = (DocuDirectory) map.get(fn); |
| 170 if (dd == null) { | |
| 171 // cache miss | |
| 172 misses++; | |
| 176 | 173 /* |
| 174 * see if it's a directory | |
| 175 */ | |
| 152 | 176 File f = new File(baseDirNames[0], fn); |
| 91 | 177 if (f.isDirectory()) { |
| 151 | 178 dd = new DocuDirectory(fn, this); |
| 91 | 179 if (dd.isValid()) { |
| 180 // add to the cache | |
| 151 | 181 putDir(dd); |
| 91 | 182 } |
| 183 } else { | |
| 176 | 184 /* |
| 185 * maybe it's a file | |
| 186 */ | |
| 187 // get the parent directory string (like we store it in the | |
| 188 // cache) | |
| 189 String d = fn.substring(0, fn.lastIndexOf("/")); | |
| 190 // try it in the cache | |
| 191 dd = (DocuDirectory) map.get(d); | |
| 192 if (dd == null) { | |
| 193 // try to read from disk | |
| 194 dd = new DocuDirectory(d, this); | |
| 195 if (dd.isValid()) { | |
| 196 // add to the cache | |
| 197 putDir(dd); | |
| 91 | 198 } else { |
| 176 | 199 // invalid path |
| 200 return null; | |
| 91 | 201 } |
|
99
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
202 } else { |
| 176 | 203 // it was not a real cache miss |
| 204 misses--; | |
| 91 | 205 } |
| 176 | 206 // get the file's index |
| 207 n = dd.indexOf(f.getName(), fc); | |
| 91 | 208 } |
| 209 } else { | |
| 210 // cache hit | |
| 211 hits++; | |
| 212 } | |
| 213 dd.refresh(); | |
| 214 if (dd.isValid()) { | |
| 215 try { | |
| 159 | 216 return dd.get(n, fc); |
| 187 | 217 } catch (IndexOutOfBoundsException e) { |
| 91 | 218 } |
| 219 } | |
| 220 return null; | |
| 221 } | |
| 222 | |
| 176 | 223 /** |
| 224 * Returns the DocuDirectory indicated by the pathname <code>fn</code>. | |
| 91 | 225 * |
| 226 * If <code>fn</code> is a file then its parent directory is returned. | |
| 227 * | |
| 176 | 228 * @param fn |
| 229 * digilib pathname | |
| 91 | 230 * @return |
| 231 */ | |
| 232 public DocuDirectory getDirectory(String fn) { | |
| 233 DocuDirectory dd; | |
| 234 // first, assume fn is a directory and look in the cache | |
| 235 dd = (DocuDirectory) map.get(fn); | |
| 86 | 236 if (dd == null) { |
| 237 // cache miss | |
| 238 misses++; | |
| 239 // see if it's a directory | |
| 152 | 240 File f = new File(baseDirNames[0], fn); |
| 86 | 241 if (f.isDirectory()) { |
| 151 | 242 dd = new DocuDirectory(fn, this); |
| 86 | 243 if (dd.isValid()) { |
| 244 // add to the cache | |
| 151 | 245 putDir(dd); |
| 86 | 246 } |
| 247 } else { | |
| 248 // maybe it's a file | |
| 249 if (f.canRead()) { | |
| 250 // try the parent directory in the cache | |
| 91 | 251 dd = (DocuDirectory) map.get(f.getParent()); |
| 86 | 252 if (dd == null) { |
| 253 // try to read from disk | |
| 151 | 254 dd = new DocuDirectory(f.getParent(), this); |
| 86 | 255 if (dd.isValid()) { |
| 256 // add to the cache | |
| 151 | 257 putDir(dd); |
| 86 | 258 } else { |
| 259 // invalid path | |
| 260 return null; | |
| 261 } | |
| 91 | 262 } else { |
| 263 // not a real cache miss then | |
| 264 misses--; | |
| 86 | 265 } |
|
99
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
266 } else { |
|
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
267 // it's not even a file :-( |
|
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
268 return null; |
| 86 | 269 } |
| 270 } | |
| 271 } else { | |
| 272 // cache hit | |
| 273 hits++; | |
| 274 } | |
| 275 dd.refresh(); | |
| 276 if (dd.isValid()) { | |
| 277 return dd; | |
| 278 } | |
| 279 return null; | |
| 280 } | |
| 281 | |
| 282 /** | |
| 283 * @return String[] | |
| 284 */ | |
| 285 public String[] getBaseDirNames() { | |
| 286 return baseDirNames; | |
| 287 } | |
| 288 | |
| 289 /** | |
| 290 * @return long | |
| 291 */ | |
| 292 public long getNumFiles() { | |
| 293 return numFiles; | |
| 294 } | |
| 295 | |
| 296 /** | |
| 297 * Sets the baseDirNames. | |
| 176 | 298 * |
| 299 * @param baseDirNames | |
| 300 * The baseDirNames to set | |
| 86 | 301 */ |
| 302 public void setBaseDirNames(String[] baseDirNames) { | |
| 303 this.baseDirNames = baseDirNames; | |
| 304 } | |
| 305 | |
| 306 /** | |
| 307 * @return long | |
| 308 */ | |
| 309 public long getHits() { | |
| 310 return hits; | |
| 311 } | |
| 312 | |
| 313 /** | |
| 314 * @return long | |
| 315 */ | |
| 316 public long getMisses() { | |
| 317 return misses; | |
| 318 } | |
| 319 | |
| 159 | 320 /** |
| 321 * @return | |
| 322 */ | |
| 323 public int[] getFileClasses() { | |
| 324 return fileClasses; | |
| 325 } | |
| 326 | |
| 327 /** | |
| 328 * @param fileClasses | |
| 329 */ | |
| 330 public void setFileClasses(int[] fileClasses) { | |
| 331 this.fileClasses = fileClasses; | |
| 332 } | |
| 176 | 333 |
| 86 | 334 } |
