Mercurial > hg > digilib-old
comparison servlet/src/digilib/io/FileOps.java @ 531:9cedd170b581 digilibPDF
* PDF generation works now even with subdirectories
* genericsification and clean up
author | robcast |
---|---|
date | Fri, 05 Feb 2010 20:58:38 +0100 |
parents | 0ff3ede32060 |
children | e758a49258e8 |
comparison
equal
deleted
inserted
replaced
530:bd6569a95a3c | 531:9cedd170b581 |
---|---|
1 /* FileOps -- Utility class for file operations | 1 /* |
2 | 2 * FileOps -- Utility class for file operations |
3 Digital Image Library servlet components | 3 * |
4 | 4 * Digital Image Library servlet components |
5 Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de) | 5 * |
6 | 6 * Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de) |
7 This program is free software; you can redistribute it and/or modify it | 7 * |
8 under the terms of the GNU General Public License as published by the | 8 * This program is free software; you can redistribute it and/or modify it |
9 Free Software Foundation; either version 2 of the License, or (at your | 9 * under the terms of the GNU General Public License as published by the Free |
10 option) any later version. | 10 * Software Foundation; either version 2 of the License, or (at your option) |
11 | 11 * any later version. |
12 Please read license.txt for the full details. A copy of the GPL | 12 * |
13 may be found at http://www.gnu.org/copyleft/lgpl.html | 13 * Please read license.txt for the full details. A copy of the GPL may be found |
14 | 14 * at http://www.gnu.org/copyleft/lgpl.html |
15 You should have received a copy of the GNU General Public License | 15 * |
16 along with this program; if not, write to the Free Software | 16 * You should have received a copy of the GNU General Public License along with |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
18 | 18 * Place, Suite 330, Boston, MA 02111-1307 USA |
19 */ | 19 * |
20 */ | |
20 | 21 |
21 package digilib.io; | 22 package digilib.io; |
22 | 23 |
23 import java.io.*; | 24 import java.io.File; |
24 import java.util.*; | 25 import java.io.FileFilter; |
25 | 26 import java.util.ArrayList; |
26 import digilib.*; | 27 import java.util.HashMap; |
27 | 28 import java.util.Iterator; |
29 import java.util.List; | |
30 import java.util.Map; | |
31 import java.util.StringTokenizer; | |
28 | 32 |
29 public class FileOps { | 33 public class FileOps { |
30 | 34 |
31 private Utils util = null; | 35 /** |
32 public static String[] fileTypes = { | 36 * Array of file extensions and corresponding mime-types. |
33 "jpg", "image/jpeg", | 37 */ |
34 "jpeg", "image/jpeg", | 38 private static final String[][] ft = { { "jpg", "image/jpeg" }, |
35 "png", "image/png", | 39 { "jpeg", "image/jpeg" }, { "jp2", "image/jp2" }, |
36 "gif", "image/gif", | 40 { "png", "image/png" }, { "gif", "image/gif" }, |
37 "tif", "image/tiff", | 41 { "tif", "image/tiff" }, { "tiff", "image/tiff" }, |
38 "tiff", "image/tiff"}; | 42 { "fpx", "image/fpx" }, |
39 | 43 { "txt", "text/plain" }, { "html", "text/html" }, |
40 public FileOps() { | 44 { "htm", "text/html" }, { "xml", "text/xml" }, |
41 util = new Utils(); | 45 { "svg", "image/svg+xml" }, { "meta", "text/xml" } }; |
42 } | 46 |
43 | 47 public static Map<String, String> fileTypes; |
44 public FileOps(Utils u) { | 48 |
45 util = u; | 49 public static List<String> imageExtensions; |
46 } | 50 |
47 | 51 public static List<String> textExtensions; |
48 public void setUtils(Utils u) { | 52 |
49 util = u; | 53 public static List<String> svgExtensions; |
50 } | 54 |
51 | 55 public static final int CLASS_NONE = -1; |
52 | 56 |
53 /** | 57 public static final int CLASS_IMAGE = 0; |
54 * get the mime type for a file format (by extension) | 58 |
55 */ | 59 public static final int CLASS_TEXT = 1; |
56 public static String mimeForFile(File f) { | 60 |
57 String fn = f.getName(); | 61 public static final int CLASS_SVG = 2; |
58 for (int i = 0; i < fileTypes.length; i += 2) { | 62 |
59 if (fn.toLowerCase().endsWith(fileTypes[i])) { | 63 public static final int NUM_CLASSES = 3; |
60 return fileTypes[i+1]; | 64 |
61 } | 65 public static final Integer HINT_BASEDIRS = new Integer(1); |
66 | |
67 public static final Integer HINT_FILEEXT = new Integer(2); | |
68 | |
69 public static final Integer HINT_DIRS = new Integer(3); | |
70 | |
71 /** | |
72 * static initializer for FileOps | |
73 */ | |
74 static { | |
75 fileTypes = new HashMap<String, String>(); | |
76 imageExtensions = new ArrayList<String>(); | |
77 textExtensions = new ArrayList<String>(); | |
78 svgExtensions = new ArrayList<String>(); | |
79 // iterate through file types in ft and fill the Map and Lists | |
80 for (int i = 0; i < ft.length; i++) { | |
81 String ext = ft[i][0]; | |
82 String mt = ft[i][1]; | |
83 fileTypes.put(ext, mt); | |
84 if (classForMimetype(mt) == CLASS_IMAGE) { | |
85 imageExtensions.add(ext); | |
86 } else if (classForMimetype(mt) == CLASS_TEXT) { | |
87 textExtensions.add(ext); | |
88 } else if (classForMimetype(mt) == CLASS_SVG) { | |
89 svgExtensions.add(ext); | |
90 } | |
91 } | |
92 } | |
93 | |
94 /** | |
95 * returns the file class for a mime-type | |
96 * | |
97 * @param mt | |
98 * @return | |
99 */ | |
100 public static int classForMimetype(String mt) { | |
101 if (mt == null) { | |
102 return CLASS_NONE; | |
103 } | |
104 if (mt.startsWith("image/svg")) { | |
105 return CLASS_SVG; | |
106 } else if (mt.startsWith("image")) { | |
107 return CLASS_IMAGE; | |
108 } else if (mt.startsWith("text")) { | |
109 return CLASS_TEXT; | |
110 } | |
111 return CLASS_NONE; | |
112 } | |
113 | |
114 /** | |
115 * get the mime type for a file format (by extension) | |
116 */ | |
117 public static String mimeForFile(File f) { | |
118 return (String) fileTypes.get(extname(f.getName().toLowerCase())); | |
119 } | |
120 | |
121 /** | |
122 * get the file class for the filename (by extension) | |
123 * | |
124 * @param fn | |
125 * @return | |
126 */ | |
127 public static int classForFilename(String fn) { | |
128 String mt = (String) fileTypes.get(extname(fn).toLowerCase()); | |
129 return classForMimetype(mt); | |
130 } | |
131 | |
132 public static Iterator<String> getImageExtensionIterator() { | |
133 return imageExtensions.iterator(); | |
134 } | |
135 | |
136 public static List<String> getImageExtensions() { | |
137 return imageExtensions; | |
62 } | 138 } |
63 return null; | 139 |
64 } | 140 public static Iterator<String> getTextExtensionIterator() { |
65 | 141 return textExtensions.iterator(); |
66 /** | 142 } |
67 * get a filehandle for a file or directory name | 143 |
68 * returns File number n if fn is directory (starts with 1) | 144 public static List<String> getTextExtensions() { |
69 */ | 145 return textExtensions; |
70 public File getFile(String fn, int n) throws FileOpException { | |
71 util.dprintln(4, "getFile ("+fn+", "+n+")"); | |
72 | |
73 File f = new File(fn); | |
74 // if fn is a file name then return file | |
75 if (f.isFile()) { | |
76 return f; | |
77 } | 146 } |
78 // if fn is a directory name then open directory | 147 |
79 if (f.isDirectory()) { | 148 public static Iterator<String> getSVGExtensionIterator() { |
80 File[] fl = f.listFiles(new ImgFileFilter()); | 149 return svgExtensions.iterator(); |
81 Arrays.sort(fl); | 150 } |
82 if ((n > 0) && (n <= fl.length)) { | 151 |
83 return fl[n - 1]; | 152 public static List<String> getSvgExtensions() { |
84 } | 153 return svgExtensions; |
85 } | 154 } |
86 throw new FileOpException("Unable to find file: "+fn); | 155 |
87 } | 156 |
88 | 157 /** |
89 /** | 158 * convert a string with a list of pathnames into an array of strings using |
90 * get the number of files in a directory | 159 * the system's path separator string |
91 * (almost the same as getFile) | 160 */ |
92 * returns 0 in case of problems | 161 public static String[] pathToArray(String paths) { |
93 */ | 162 // split list into directories |
94 public int getNumFiles(String fn) throws FileOpException { | 163 StringTokenizer dirs = new StringTokenizer(paths, File.pathSeparator); |
95 util.dprintln(4, "getNumFiles ("+fn+")"); | 164 int n = dirs.countTokens(); |
96 | 165 if (n < 1) { |
97 File f = new File(fn); | 166 return null; |
98 // if fn is a file name then return 1 | 167 } |
99 if (f.isFile()) { | 168 // add directories into array |
100 return 1; | 169 String[] pathArray = new String[n]; |
101 } | 170 for (int i = 0; i < n; i++) { |
102 // if fn is a directory name then return the number of files | 171 String s = dirs.nextToken(); |
103 if (f.isDirectory()) { | 172 // make shure the dir name ends with a directory separator |
104 return f.listFiles(new ImgFileFilter()).length; | 173 if (s.endsWith(File.separator)) { |
105 } | 174 pathArray[i] = s; |
106 // then fn must be something strange... | 175 } else { |
107 return 0; | 176 pathArray[i] = s + File.separator; |
108 } | 177 } |
109 | 178 } |
110 | 179 return pathArray; |
111 /** | 180 } |
112 * get a filehandle for a file or directory name out of a list | 181 |
113 * dirs is a list of base directories, fn is the appended file/dirname | 182 /** |
114 * searches dirs until fn exists (backwards if fwd is false) | 183 * Extract the base of a file name (sans extension). |
115 * returns File number n if fn is directory (starts with 1) | 184 * |
116 */ | 185 * Returns the filename without the extension. The extension is the part |
117 public File getFileVariant(String[] dirs, String fn, int n, boolean fwd) throws FileOpException { | 186 * behind the last dot in the filename. If the filename has no dot the full |
118 util.dprintln(4, "getVariantFile ("+dirs+", "+fn+", "+n+")"); | 187 * file name is returned. |
119 | 188 * |
120 File f = null; | 189 * @param fn |
121 int start = 0; | 190 * @return |
122 int inc = 1; | 191 */ |
123 int end = dirs.length; | 192 public static String basename(String fn) { |
124 if (fwd == false) { | 193 if (fn == null) { |
125 start = dirs.length - 1; | 194 return null; |
126 inc = -1; | 195 } |
127 end = 0; | 196 int i = fn.lastIndexOf('.'); |
128 } | 197 if (i > 0) { |
129 | 198 return fn.substring(0, i); |
130 for (int i = start; i != end; i += inc) { | 199 } |
131 try { | 200 return fn; |
132 f = getFile(dirs[i]+fn, n); | 201 } |
133 } catch (FileOpException e) { | 202 |
134 f = null; | 203 /** |
135 } | 204 * Extract the extension of a file name. |
136 if (f != null) { | 205 * |
137 return f; | 206 * Returns the extension of a file name. The extension is the part behind |
138 } | 207 * the last dot in the filename. If the filename has no dot the empty string |
139 } | 208 * is returned. |
140 throw new FileOpException("Unable to find file: "+fn); | 209 * |
141 } | 210 * @param fn |
142 | 211 * @return |
143 /** | 212 */ |
144 * get the number of files in a directory | 213 public static String extname(String fn) { |
145 * (almost the same as getFileVariant) | 214 if (fn == null) { |
146 * returns 0 in case of problems | 215 return null; |
147 */ | 216 } |
148 public int getNumFilesVariant(String[] dirs, String fn, boolean fwd) throws FileOpException { | 217 int i = fn.lastIndexOf('.'); |
149 util.dprintln(4, "getNumFilesVariant ("+dirs+", "+fn+")"); | 218 if (i > 0) { |
150 | 219 return fn.substring(i + 1); |
151 int nf = 0; | 220 } |
152 int start = 0; | 221 return ""; |
153 int inc = 1; | 222 } |
154 int end = dirs.length; | 223 |
155 if (fwd == false) { | 224 /** |
156 start = dirs.length - 1; | 225 * Extract the parent directory of a (digilib) path name. |
157 inc = -1; | 226 * |
158 end = 0; | 227 * Returns the parent directory of a path name. The parent is the part |
159 } | 228 * before the last slash in the path name. If the path name has no slash the |
160 | 229 * empty string is returned. |
161 for (int i = start; i != end; i += inc) { | 230 * |
162 try { | 231 * @param fn |
163 nf = getNumFiles(dirs[i]+fn); | 232 * @return |
164 } catch (FileOpException e) { | 233 */ |
165 nf = 0; | 234 public static String parent(String fn) { |
166 } | 235 if (fn == null) { |
167 if (nf > 0) { | 236 return null; |
168 return nf; | 237 } |
169 } | 238 int i = fn.lastIndexOf('/'); |
170 } | 239 if (i > 0) { |
171 return 0; | 240 return fn.substring(0, i); |
172 } | 241 } |
173 | 242 return ""; |
174 /** | 243 } |
175 * FileFilter for image types (helper class for getFile) | 244 |
176 */ | 245 /** |
177 private class ImgFileFilter implements FileFilter { | 246 * Normalize a path name. |
178 | 247 * |
179 public boolean accept(File f) { | 248 * Removes leading and trailing slashes. Returns null if there is other |
180 if (f.isFile()) { | 249 * unwanted stuff in the path name. |
181 return (mimeForFile(f) != null); | 250 * |
182 } else { | 251 * @param pathname |
183 return false; | 252 * @return |
184 } | 253 */ |
185 } | 254 public static String normalName(String pathname) { |
186 } | 255 if (pathname == null) { |
256 return null; | |
257 } | |
258 // upper-dir references are unwanted | |
259 if (pathname.indexOf("../") >= 0) { | |
260 return null; | |
261 } | |
262 int a = 0; | |
263 int e = pathname.length() - 1; | |
264 if (e < 0) { | |
265 return pathname; | |
266 } | |
267 // leading and trailing "/" are removed | |
268 while ((a <= e) && (pathname.charAt(a) == '/')) { | |
269 a++; | |
270 } | |
271 while ((a < e) && (pathname.charAt(e) == '/')) { | |
272 e--; | |
273 } | |
274 return pathname.substring(a, e + 1); | |
275 } | |
276 | |
277 /** | |
278 * FileFilter for general files | |
279 */ | |
280 static class ReadableFileFilter implements FileFilter { | |
281 | |
282 public boolean accept(File f) { | |
283 return f.canRead(); | |
284 } | |
285 } | |
286 | |
287 /** | |
288 * FileFilter for image types (helper class for getFile) | |
289 */ | |
290 static class ImageFileFilter implements FileFilter { | |
291 | |
292 public boolean accept(File f) { | |
293 return (classForFilename(f.getName()) == CLASS_IMAGE); | |
294 } | |
295 } | |
296 | |
297 /** | |
298 * FileFilter for text types (helper class for getFile) | |
299 */ | |
300 static class TextFileFilter implements FileFilter { | |
301 | |
302 public boolean accept(File f) { | |
303 return (classForFilename(f.getName()) == CLASS_TEXT); | |
304 } | |
305 } | |
306 | |
307 /** | |
308 * FileFilter for svg types (helper class for getFile). | |
309 * | |
310 */ | |
311 static class SVGFileFilter implements FileFilter { | |
312 | |
313 public boolean accept(File f) { | |
314 return (classForFilename(f.getName()) == CLASS_SVG); | |
315 } | |
316 } | |
317 | |
318 /** | |
319 * Factory for FileFilters (image or text). | |
320 * | |
321 * @param fileClass | |
322 * @return | |
323 */ | |
324 public static FileFilter filterForClass(int fileClass) { | |
325 if (fileClass == CLASS_IMAGE) { | |
326 return new ImageFileFilter(); | |
327 } | |
328 if (fileClass == CLASS_TEXT) { | |
329 return new TextFileFilter(); | |
330 } | |
331 if (fileClass == CLASS_SVG) { | |
332 return new SVGFileFilter(); | |
333 } | |
334 return null; | |
335 } | |
336 | |
337 /** | |
338 * Factory for DocuDirents based on file class. | |
339 * | |
340 * Returns an ImageFileset, TextFile or SVGFile. baseDirs and scalext are | |
341 * only for ImageFilesets. | |
342 * | |
343 * @param fileClass | |
344 * @param file | |
345 * @param hints | |
346 * optional additional parameters | |
347 * @return | |
348 */ | |
349 public static DocuDirent fileForClass(int fileClass, File file, Map<Integer,Object> hints) { | |
350 // what class of file do we have? | |
351 if (fileClass == CLASS_IMAGE) { | |
352 // image file | |
353 return new ImageFileset(file, hints); | |
354 } else if (fileClass == CLASS_TEXT) { | |
355 // text file | |
356 return new TextFile(file); | |
357 } else if (fileClass == CLASS_SVG) { | |
358 // text file | |
359 return new SVGFile(file); | |
360 } | |
361 return null; | |
362 } | |
363 | |
364 /** | |
365 * Filters a list of Files through a FileFilter. | |
366 * | |
367 * @param files | |
368 * @param filter | |
369 * @return | |
370 */ | |
371 public static File[] listFiles(File[] files, FileFilter filter) { | |
372 if (files == null) { | |
373 return null; | |
374 } | |
375 File[] ff = new File[files.length]; | |
376 int ffi = 0; | |
377 for (int i = 0; i < files.length; i++) { | |
378 if (filter.accept(files[i])) { | |
379 ff[ffi] = files[i]; | |
380 ffi++; | |
381 } | |
382 } | |
383 File[] fff = new File[ffi]; | |
384 System.arraycopy(ff, 0, fff, 0, ffi); | |
385 return fff; | |
386 } | |
387 | |
388 /** | |
389 * Creates a new hints Map with the given first element. | |
390 * | |
391 * @param type | |
392 * @param value | |
393 * @return | |
394 */ | |
395 public static Map<Integer, Object> newHints(Integer type, Object value) { | |
396 Map<Integer, Object> m = new HashMap<Integer, Object>(); | |
397 if (type != null) { | |
398 m.put(type, value); | |
399 } | |
400 return m; | |
401 } | |
187 | 402 |
188 } | 403 } |