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 }