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