Mercurial > hg > digilib-old
annotate servlet/src/digilib/io/DocuDirCache.java @ 582:c7034d166a24 stream
more ripping apart ImageFileSet
author | robcast |
---|---|
date | Tue, 04 Jan 2011 11:56:12 +0100 |
parents | 686086d6e6d6 |
children | 4f5aaa0de456 |
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.LinkedList; |
28 import java.util.List; | |
270 | 29 import java.util.Map; |
86 | 30 |
181 | 31 import org.apache.log4j.Logger; |
32 | |
563 | 33 import digilib.io.FileOps.FileClass; |
259 | 34 import digilib.servlet.DigilibConfiguration; |
35 | |
86 | 36 /** |
37 * @author casties | |
38 */ | |
91 | 39 public class DocuDirCache { |
86 | 40 |
181 | 41 /** general logger for this class */ |
270 | 42 Logger logger = Logger.getLogger(this.getClass()); |
282 | 43 |
159 | 44 /** HashMap of directories */ |
531 | 45 Map<String, DocuDirectory> map = null; |
282 | 46 |
159 | 47 /** names of base directories */ |
270 | 48 String[] baseDirNames = null; |
282 | 49 |
159 | 50 /** array of allowed file classes (image/text) */ |
563 | 51 private FileClass[] fileClasses = null; |
282 | 52 |
159 | 53 /** number of files in the whole cache (approximate) */ |
270 | 54 long numFiles = 0; |
282 | 55 |
159 | 56 /** number of cache hits */ |
270 | 57 long hits = 0; |
282 | 58 |
159 | 59 /** number of cache misses */ |
270 | 60 long misses = 0; |
282 | 61 |
270 | 62 /** the root directory element */ |
63 public static Directory ROOT = null; | |
86 | 64 |
176 | 65 /** |
66 * Constructor with array of base directory names and file classes. | |
67 * | |
68 * @param bd | |
69 * base directory names | |
159 | 70 */ |
563 | 71 public DocuDirCache(String[] bd, FileClass[] fcs, |
282 | 72 DigilibConfiguration dlConfig) { |
159 | 73 baseDirNames = bd; |
531 | 74 map = new HashMap<String, DocuDirectory>(); |
563 | 75 this.fileClasses = fcs; |
159 | 76 } |
282 | 77 |
176 | 78 /** |
79 * Constructor with array of base directory names. | |
80 * | |
81 * @param bd | |
82 * base directory names | |
86 | 83 */ |
84 public DocuDirCache(String[] bd) { | |
85 baseDirNames = bd; | |
531 | 86 map = new HashMap<String, DocuDirectory>(); |
159 | 87 // default file class is CLASS_IMAGE |
563 | 88 fileClasses = new FileClass[] { FileClass.IMAGE }; |
91 | 89 } |
90 | |
176 | 91 /** |
92 * The number of directories in the cache. | |
93 * | |
91 | 94 * @return |
95 */ | |
96 public int size() { | |
97 return (map != null) ? map.size() : 0; | |
86 | 98 } |
99 | |
176 | 100 /** |
101 * Add a DocuDirectory to the cache. | |
86 | 102 * |
103 * @param newdir | |
104 */ | |
105 public void put(DocuDirectory newdir) { | |
106 String s = newdir.getDirName(); | |
91 | 107 if (map.containsKey(s)) { |
197 | 108 logger.warn("Duplicate key in DocuDirCache.put -- ignoring!"); |
86 | 109 } else { |
91 | 110 map.put(s, newdir); |
86 | 111 numFiles += newdir.size(); |
112 } | |
113 } | |
114 | |
176 | 115 /** |
116 * Add a directory to the cache and check its parents. | |
151 | 117 * |
118 * @param newDir | |
119 */ | |
282 | 120 public synchronized void putDir(DocuDirectory newDir) { |
151 | 121 put(newDir); |
270 | 122 String parent = FileOps.parent(newDir.getDirName()); |
123 if (parent != "") { | |
151 | 124 // check the parent in the cache |
563 | 125 DocuDirectory pd = map.get(parent); |
151 | 126 if (pd == null) { |
127 // the parent is unknown | |
128 pd = new DocuDirectory(parent, this); | |
129 putDir(pd); | |
130 } | |
131 newDir.setParent(pd); | |
132 } | |
133 } | |
134 | |
176 | 135 /** |
136 * Get a list with all children of a directory. | |
159 | 137 * |
282 | 138 * Returns a List of DocuDirectory's. Returns an empty List if the directory |
139 * has no children. If recurse is false then only direct children are | |
140 * returned. | |
159 | 141 * |
142 * @param dirname | |
176 | 143 * @param recurse |
144 * find all children and their children. | |
159 | 145 * @return |
146 */ | |
531 | 147 public List<DocuDirectory> getChildren(String dirname, boolean recurse) { |
148 List<DocuDirectory> l = new LinkedList<DocuDirectory>(); | |
149 for (DocuDirectory dd: map.values()) { | |
159 | 150 if (recurse) { |
151 if (dd.getDirName().startsWith(dirname)) { | |
152 l.add(dd); | |
153 } | |
154 } else { | |
270 | 155 if (FileOps.parent(dd.getDirName()).equals(dirname)) { |
159 | 156 l.add(dd); |
157 } | |
158 } | |
159 } | |
160 return l; | |
161 } | |
162 | |
176 | 163 /** |
282 | 164 * Returns the DocuDirent with the pathname <code>fn</code> and the index |
165 * <code>in</code> and the class <code>fc</code>. | |
91 | 166 * |
187 | 167 * If <code>fn</code> is a file then the corresponding DocuDirent is |
91 | 168 * returned and the index is ignored. |
169 * | |
176 | 170 * @param fn |
171 * digilib pathname | |
172 * @param in | |
173 * file index | |
246 | 174 * @param fc |
282 | 175 * file class |
176 | 176 * @return |
91 | 177 */ |
563 | 178 public DocuDirent getFile(String fn, int in, FileClass fc) { |
86 | 179 DocuDirectory dd; |
180 // file number is 1-based, vector index is 0-based | |
181 int n = in - 1; | |
182 // first, assume fn is a directory and look in the cache | |
563 | 183 dd = map.get(fn); |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
184 // logger.debug("fn: " + fn); |
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
185 // logger.debug("dd: " + dd); |
91 | 186 if (dd == null) { |
187 // cache miss | |
188 misses++; | |
176 | 189 /* |
287 | 190 * see if fn is a directory |
176 | 191 */ |
152 | 192 File f = new File(baseDirNames[0], fn); |
91 | 193 if (f.isDirectory()) { |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
194 // logger.debug(fn + " is a dir"); |
151 | 195 dd = new DocuDirectory(fn, this); |
91 | 196 if (dd.isValid()) { |
197 // add to the cache | |
151 | 198 putDir(dd); |
91 | 199 } |
200 } else { | |
176 | 201 /* |
202 * maybe it's a file | |
203 */ | |
204 // get the parent directory string (like we store it in the | |
205 // cache) | |
246 | 206 String d = FileOps.parent(fn); |
176 | 207 // try it in the cache |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
208 // logger.debug(fn + " is a file in dir " + d); |
563 | 209 dd = map.get(d); |
176 | 210 if (dd == null) { |
211 // try to read from disk | |
212 dd = new DocuDirectory(d, this); | |
213 if (dd.isValid()) { | |
214 // add to the cache | |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
215 // logger.debug(dd + " is valid"); |
176 | 216 putDir(dd); |
91 | 217 } else { |
176 | 218 // invalid path |
219 return null; | |
91 | 220 } |
99
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
221 } else { |
176 | 222 // it was not a real cache miss |
223 misses--; | |
91 | 224 } |
176 | 225 // get the file's index |
226 n = dd.indexOf(f.getName(), fc); | |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
227 // logger.debug(f.getName() + ", index is " + n + ", fc = " + fc); |
91 | 228 } |
229 } else { | |
230 // cache hit | |
231 hits++; | |
232 } | |
233 dd.refresh(); | |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
234 // logger.debug(dd + " refreshed"); |
91 | 235 if (dd.isValid()) { |
236 try { | |
472
f8ca069517a2
Bugfix for images not found in dir: added sorting for ArrayLists of ImageFilesets
hertzhaft
parents:
287
diff
changeset
|
237 // logger.debug(dd + " is valid"); |
159 | 238 return dd.get(n, fc); |
187 | 239 } catch (IndexOutOfBoundsException e) { |
473
fca40a188a22
modified DocuDirent.compareTo instead of ImageFileset.compareTo
hertzhaft
parents:
472
diff
changeset
|
240 // logger.debug(fn + " not found in directory"); |
91 | 241 } |
242 } | |
243 return null; | |
244 } | |
245 | |
176 | 246 /** |
247 * Returns the DocuDirectory indicated by the pathname <code>fn</code>. | |
91 | 248 * |
249 * If <code>fn</code> is a file then its parent directory is returned. | |
250 * | |
176 | 251 * @param fn |
252 * digilib pathname | |
91 | 253 * @return |
254 */ | |
255 public DocuDirectory getDirectory(String fn) { | |
256 DocuDirectory dd; | |
257 // first, assume fn is a directory and look in the cache | |
563 | 258 dd = map.get(fn); |
86 | 259 if (dd == null) { |
260 // cache miss | |
261 misses++; | |
262 // see if it's a directory | |
152 | 263 File f = new File(baseDirNames[0], fn); |
86 | 264 if (f.isDirectory()) { |
151 | 265 dd = new DocuDirectory(fn, this); |
86 | 266 if (dd.isValid()) { |
267 // add to the cache | |
151 | 268 putDir(dd); |
86 | 269 } |
270 } else { | |
271 // maybe it's a file | |
272 if (f.canRead()) { | |
273 // try the parent directory in the cache | |
563 | 274 dd = map.get(f.getParent()); |
86 | 275 if (dd == null) { |
276 // try to read from disk | |
151 | 277 dd = new DocuDirectory(f.getParent(), this); |
86 | 278 if (dd.isValid()) { |
279 // add to the cache | |
151 | 280 putDir(dd); |
86 | 281 } else { |
282 // invalid path | |
283 return null; | |
284 } | |
91 | 285 } else { |
286 // not a real cache miss then | |
287 misses--; | |
86 | 288 } |
99
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
289 } else { |
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
290 // it's not even a file :-( |
226624784fe3
Small bug lead to null pointer exception when directory doesn't exist.
robcast
parents:
91
diff
changeset
|
291 return null; |
86 | 292 } |
293 } | |
294 } else { | |
295 // cache hit | |
296 hits++; | |
297 } | |
298 dd.refresh(); | |
299 if (dd.isValid()) { | |
300 return dd; | |
301 } | |
302 return null; | |
303 } | |
304 | |
305 /** | |
306 * @return String[] | |
307 */ | |
308 public String[] getBaseDirNames() { | |
309 return baseDirNames; | |
310 } | |
311 | |
312 /** | |
313 * @return long | |
314 */ | |
315 public long getNumFiles() { | |
316 return numFiles; | |
317 } | |
318 | |
319 /** | |
320 * Sets the baseDirNames. | |
176 | 321 * |
322 * @param baseDirNames | |
323 * The baseDirNames to set | |
86 | 324 */ |
325 public void setBaseDirNames(String[] baseDirNames) { | |
326 this.baseDirNames = baseDirNames; | |
327 } | |
328 | |
329 /** | |
330 * @return long | |
331 */ | |
332 public long getHits() { | |
333 return hits; | |
334 } | |
335 | |
336 /** | |
337 * @return long | |
338 */ | |
339 public long getMisses() { | |
340 return misses; | |
341 } | |
342 | |
159 | 343 /** |
344 * @return | |
345 */ | |
563 | 346 public FileClass[] getFileClasses() { |
159 | 347 return fileClasses; |
348 } | |
349 | |
350 /** | |
351 * @param fileClasses | |
352 */ | |
563 | 353 public void setFileClasses(FileClass[] fileClasses) { |
159 | 354 this.fileClasses = fileClasses; |
355 } | |
176 | 356 |
86 | 357 } |