339
|
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 *
|
|
20 * Created on 03.03.2003
|
|
21 */
|
|
22
|
|
23 package digilib.io;
|
|
24
|
|
25 import java.io.File;
|
|
26 import java.util.HashMap;
|
|
27 import java.util.Map;
|
|
28
|
|
29 import org.apache.log4j.Logger;
|
|
30
|
|
31 /**
|
|
32 * Cache of digilib directories.
|
|
33 *
|
|
34 * @author casties
|
|
35 */
|
|
36 public class DocuDirCache {
|
|
37
|
|
38 /** general logger for this class */
|
|
39 protected static Logger logger = Logger.getLogger(DocuDirCache.class);
|
|
40
|
|
41 /** Map of directories */
|
|
42 Map map = null;
|
|
43
|
|
44 /** number of files in the whole cache (approximate) */
|
|
45 long numFiles = 0;
|
|
46
|
|
47 /** number of cache hits */
|
|
48 long hits = 0;
|
|
49
|
|
50 /** number of cache misses */
|
|
51 long misses = 0;
|
|
52
|
|
53 /** the root directory element */
|
|
54 public DigiDirectory rootDir = null;
|
|
55
|
|
56 /**
|
|
57 * Default constructor.
|
|
58 */
|
|
59 public DocuDirCache() {
|
|
60 map = new HashMap();
|
|
61 // add root directory
|
|
62 rootDir = new DigiDirectory(FileOps.getBaseDirs()[0], "", null);
|
|
63 map.put("", rootDir);
|
|
64 }
|
|
65
|
|
66 /**
|
|
67 * The number of directories in the cache.
|
|
68 *
|
|
69 * @return
|
|
70 */
|
|
71 public int size() {
|
|
72 return (map != null) ? map.size() : 0;
|
|
73 }
|
|
74
|
|
75 /**
|
|
76 * Add a DocuDirectory to the cache.
|
|
77 *
|
|
78 * @param newdir
|
|
79 */
|
|
80 public void put(DigiDirectory newdir) {
|
|
81 String s = newdir.getDLPath();
|
|
82 Object oldkey = map.put(s, newdir);
|
|
83 if (oldkey != null) {
|
|
84 logger.warn("Duplicate key in DocuDirCache.put -- overwritten!");
|
|
85 }
|
|
86 numFiles += newdir.getSize();
|
|
87 }
|
|
88
|
|
89 /**
|
|
90 * Add a directory to the cache and check its parents.
|
|
91 *
|
|
92 * @param newDir
|
|
93 */
|
|
94 public synchronized void putDir(DigiDirectory newDir) {
|
|
95 put(newDir);
|
|
96 }
|
|
97
|
|
98 /**
|
|
99 * Returns a DigiDirectory from the cache.
|
|
100 *
|
|
101 * @param path
|
|
102 * @return
|
|
103 */
|
|
104 public DigiDirectory get(String path) {
|
|
105 return (DigiDirectory) map.get(path);
|
|
106 }
|
|
107
|
|
108 /**
|
|
109 * Returns the DigiDirectory indicated by the pathname <code>fn</code>.
|
|
110 *
|
|
111 * If <code>fn</code> is a file then its parent directory is returned.
|
|
112 *
|
|
113 * @param fn
|
|
114 * digilib pathname
|
|
115 * @return
|
|
116 */
|
|
117 public DigiDirectory getDirectory(String pn) {
|
|
118 /*
|
|
119 * first, assume pn is a directory and look in the cache
|
|
120 */
|
|
121 DigiDirectory dd = (DigiDirectory) map.get(pn);
|
|
122 if (dd != null) {
|
|
123 // cache hit
|
|
124 hits++;
|
|
125 return dd;
|
|
126 } else {
|
|
127 /*
|
|
128 * maybe it's a file? try the parent directory
|
|
129 */
|
|
130 String dn = FileOps.dlParent(pn);
|
|
131 // try it in the cache
|
|
132 dd = (DigiDirectory) map.get(dn);
|
|
133 if (dd != null) {
|
|
134 // cache hit
|
|
135 hits++;
|
|
136 return dd;
|
|
137 } else {
|
|
138 // cache miss
|
|
139 misses++;
|
|
140 /*
|
|
141 * try to read from disk
|
|
142 */
|
|
143 File f = FileOps.getRealFile(pn);
|
|
144 /*
|
|
145 * is it a directory?
|
|
146 */
|
|
147 if (f.isDirectory()) {
|
|
148 dd = new DigiDirectory(f, pn, null);
|
|
149 // add to the cache
|
|
150 putDir(dd);
|
|
151 return dd;
|
|
152 } else {
|
|
153 /*
|
|
154 * then maybe a file? try the parent as a directory
|
|
155 */
|
|
156 File d = FileOps.getRealFile(dn);
|
|
157 if (d.isDirectory()) {
|
|
158 dd = new DigiDirectory(d, dn, null);
|
|
159 // add to the cache
|
|
160 putDir(dd);
|
|
161 return dd;
|
|
162 }
|
|
163 }
|
|
164 }
|
|
165 }
|
|
166 /*
|
|
167 * otherwise it's crap
|
|
168 */
|
|
169 return null;
|
|
170 }
|
|
171
|
|
172 /**
|
|
173 * Returns the DigiDirent with the pathname <code>fn</code> and the index
|
|
174 * <code>in</code> and the class <code>fc</code>.
|
|
175 *
|
|
176 * If <code>fn</code> is a file then the corresponding DocuDirent is
|
|
177 * returned and the index is ignored.
|
|
178 *
|
|
179 * @param pn
|
|
180 * digilib pathname
|
|
181 * @param in
|
|
182 * file index
|
|
183 * @param fc
|
|
184 * file class
|
|
185 * @return
|
|
186 */
|
|
187 public DigiDirent getFile(String pn, int in, int fc) {
|
|
188 // file number is 1-based, vector index is 0-based
|
|
189 int n = in - 1;
|
|
190 // get the (parent) directory
|
|
191 DigiDirectory dd = getDirectory(pn);
|
|
192 if (dd != null) {
|
|
193 // get the directory's name
|
|
194 String dn = dd.getDLPath();
|
|
195 if (dn.equals(pn)) {
|
|
196 // return the file at the index
|
|
197 return dd.get(n, fc);
|
|
198 } else {
|
|
199 // then the last part must be the filename
|
|
200 String fn = FileOps.dlName(pn);
|
|
201 return dd.get(fn);
|
|
202 }
|
|
203 }
|
|
204 return null;
|
|
205 }
|
|
206
|
|
207 /**
|
|
208 * @return long
|
|
209 */
|
|
210 public long getNumFiles() {
|
|
211 return numFiles;
|
|
212 }
|
|
213
|
|
214 /**
|
|
215 * @return long
|
|
216 */
|
|
217 public long getHits() {
|
|
218 return hits;
|
|
219 }
|
|
220
|
|
221 /**
|
|
222 * @return long
|
|
223 */
|
|
224 public long getMisses() {
|
|
225 return misses;
|
|
226 }
|
|
227
|
|
228 /**
|
|
229 * @return Returns the rootDir.
|
|
230 */
|
|
231 public DigiDirectory getRootDir() {
|
|
232 return rootDir;
|
|
233 }
|
|
234 /**
|
|
235 * @param rootDir The rootDir to set.
|
|
236 */
|
|
237 public void setRootDir(DigiDirectory rootDir) {
|
|
238 this.rootDir = rootDir;
|
|
239 }
|
|
240 }
|