Mercurial > hg > digilib-old
diff 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 |
line wrap: on
line diff
--- a/servlet/src/digilib/io/FileOps.java Thu Jan 14 14:30:30 2010 +0100 +++ b/servlet/src/digilib/io/FileOps.java Fri Feb 05 20:58:38 2010 +0100 @@ -1,188 +1,403 @@ -/* FileOps -- Utility class for file operations - - Digital Image Library servlet components - - Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de) - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - Please read license.txt for the full details. A copy of the GPL - may be found at http://www.gnu.org/copyleft/lgpl.html - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ +/* + * FileOps -- Utility class for file operations + * + * Digital Image Library servlet components + * + * Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Please read license.txt for the full details. A copy of the GPL may be found + * at http://www.gnu.org/copyleft/lgpl.html + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + */ package digilib.io; -import java.io.*; -import java.util.*; - -import digilib.*; - +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; public class FileOps { - private Utils util = null; - public static String[] fileTypes = { - "jpg", "image/jpeg", - "jpeg", "image/jpeg", - "png", "image/png", - "gif", "image/gif", - "tif", "image/tiff", - "tiff", "image/tiff"}; + /** + * Array of file extensions and corresponding mime-types. + */ + private static final String[][] ft = { { "jpg", "image/jpeg" }, + { "jpeg", "image/jpeg" }, { "jp2", "image/jp2" }, + { "png", "image/png" }, { "gif", "image/gif" }, + { "tif", "image/tiff" }, { "tiff", "image/tiff" }, + { "fpx", "image/fpx" }, + { "txt", "text/plain" }, { "html", "text/html" }, + { "htm", "text/html" }, { "xml", "text/xml" }, + { "svg", "image/svg+xml" }, { "meta", "text/xml" } }; + + public static Map<String, String> fileTypes; + + public static List<String> imageExtensions; + + public static List<String> textExtensions; + + public static List<String> svgExtensions; + + public static final int CLASS_NONE = -1; + + public static final int CLASS_IMAGE = 0; + + public static final int CLASS_TEXT = 1; + + public static final int CLASS_SVG = 2; + + public static final int NUM_CLASSES = 3; + + public static final Integer HINT_BASEDIRS = new Integer(1); + + public static final Integer HINT_FILEEXT = new Integer(2); + + public static final Integer HINT_DIRS = new Integer(3); + + /** + * static initializer for FileOps + */ + static { + fileTypes = new HashMap<String, String>(); + imageExtensions = new ArrayList<String>(); + textExtensions = new ArrayList<String>(); + svgExtensions = new ArrayList<String>(); + // iterate through file types in ft and fill the Map and Lists + for (int i = 0; i < ft.length; i++) { + String ext = ft[i][0]; + String mt = ft[i][1]; + fileTypes.put(ext, mt); + if (classForMimetype(mt) == CLASS_IMAGE) { + imageExtensions.add(ext); + } else if (classForMimetype(mt) == CLASS_TEXT) { + textExtensions.add(ext); + } else if (classForMimetype(mt) == CLASS_SVG) { + svgExtensions.add(ext); + } + } + } - public FileOps() { - util = new Utils(); - } + /** + * returns the file class for a mime-type + * + * @param mt + * @return + */ + public static int classForMimetype(String mt) { + if (mt == null) { + return CLASS_NONE; + } + if (mt.startsWith("image/svg")) { + return CLASS_SVG; + } else if (mt.startsWith("image")) { + return CLASS_IMAGE; + } else if (mt.startsWith("text")) { + return CLASS_TEXT; + } + return CLASS_NONE; + } + + /** + * get the mime type for a file format (by extension) + */ + public static String mimeForFile(File f) { + return (String) fileTypes.get(extname(f.getName().toLowerCase())); + } - public FileOps(Utils u) { - util = u; - } + /** + * get the file class for the filename (by extension) + * + * @param fn + * @return + */ + public static int classForFilename(String fn) { + String mt = (String) fileTypes.get(extname(fn).toLowerCase()); + return classForMimetype(mt); + } + + public static Iterator<String> getImageExtensionIterator() { + return imageExtensions.iterator(); + } - public void setUtils(Utils u) { - util = u; - } + public static List<String> getImageExtensions() { + return imageExtensions; + } + + public static Iterator<String> getTextExtensionIterator() { + return textExtensions.iterator(); + } + + public static List<String> getTextExtensions() { + return textExtensions; + } + + public static Iterator<String> getSVGExtensionIterator() { + return svgExtensions.iterator(); + } + + public static List<String> getSvgExtensions() { + return svgExtensions; + } - /** - * get the mime type for a file format (by extension) - */ - public static String mimeForFile(File f) { - String fn = f.getName(); - for (int i = 0; i < fileTypes.length; i += 2) { - if (fn.toLowerCase().endsWith(fileTypes[i])) { - return fileTypes[i+1]; - } - } - return null; - } + /** + * convert a string with a list of pathnames into an array of strings using + * the system's path separator string + */ + public static String[] pathToArray(String paths) { + // split list into directories + StringTokenizer dirs = new StringTokenizer(paths, File.pathSeparator); + int n = dirs.countTokens(); + if (n < 1) { + return null; + } + // add directories into array + String[] pathArray = new String[n]; + for (int i = 0; i < n; i++) { + String s = dirs.nextToken(); + // make shure the dir name ends with a directory separator + if (s.endsWith(File.separator)) { + pathArray[i] = s; + } else { + pathArray[i] = s + File.separator; + } + } + return pathArray; + } - /** - * get a filehandle for a file or directory name - * returns File number n if fn is directory (starts with 1) - */ - public File getFile(String fn, int n) throws FileOpException { - util.dprintln(4, "getFile ("+fn+", "+n+")"); + /** + * Extract the base of a file name (sans extension). + * + * Returns the filename without the extension. The extension is the part + * behind the last dot in the filename. If the filename has no dot the full + * file name is returned. + * + * @param fn + * @return + */ + public static String basename(String fn) { + if (fn == null) { + return null; + } + int i = fn.lastIndexOf('.'); + if (i > 0) { + return fn.substring(0, i); + } + return fn; + } - File f = new File(fn); - // if fn is a file name then return file - if (f.isFile()) { - return f; - } - // if fn is a directory name then open directory - if (f.isDirectory()) { - File[] fl = f.listFiles(new ImgFileFilter()); - Arrays.sort(fl); - if ((n > 0) && (n <= fl.length)) { - return fl[n - 1]; - } - } - throw new FileOpException("Unable to find file: "+fn); - } + /** + * Extract the extension of a file name. + * + * Returns the extension of a file name. The extension is the part behind + * the last dot in the filename. If the filename has no dot the empty string + * is returned. + * + * @param fn + * @return + */ + public static String extname(String fn) { + if (fn == null) { + return null; + } + int i = fn.lastIndexOf('.'); + if (i > 0) { + return fn.substring(i + 1); + } + return ""; + } - /** - * get the number of files in a directory - * (almost the same as getFile) - * returns 0 in case of problems - */ - public int getNumFiles(String fn) throws FileOpException { - util.dprintln(4, "getNumFiles ("+fn+")"); + /** + * Extract the parent directory of a (digilib) path name. + * + * Returns the parent directory of a path name. The parent is the part + * before the last slash in the path name. If the path name has no slash the + * empty string is returned. + * + * @param fn + * @return + */ + public static String parent(String fn) { + if (fn == null) { + return null; + } + int i = fn.lastIndexOf('/'); + if (i > 0) { + return fn.substring(0, i); + } + return ""; + } - File f = new File(fn); - // if fn is a file name then return 1 - if (f.isFile()) { - return 1; - } - // if fn is a directory name then return the number of files - if (f.isDirectory()) { - return f.listFiles(new ImgFileFilter()).length; - } - // then fn must be something strange... - return 0; - } - - - /** - * get a filehandle for a file or directory name out of a list - * dirs is a list of base directories, fn is the appended file/dirname - * searches dirs until fn exists (backwards if fwd is false) - * returns File number n if fn is directory (starts with 1) - */ - public File getFileVariant(String[] dirs, String fn, int n, boolean fwd) throws FileOpException { - util.dprintln(4, "getVariantFile ("+dirs+", "+fn+", "+n+")"); + /** + * Normalize a path name. + * + * Removes leading and trailing slashes. Returns null if there is other + * unwanted stuff in the path name. + * + * @param pathname + * @return + */ + public static String normalName(String pathname) { + if (pathname == null) { + return null; + } + // upper-dir references are unwanted + if (pathname.indexOf("../") >= 0) { + return null; + } + int a = 0; + int e = pathname.length() - 1; + if (e < 0) { + return pathname; + } + // leading and trailing "/" are removed + while ((a <= e) && (pathname.charAt(a) == '/')) { + a++; + } + while ((a < e) && (pathname.charAt(e) == '/')) { + e--; + } + return pathname.substring(a, e + 1); + } - File f = null; - int start = 0; - int inc = 1; - int end = dirs.length; - if (fwd == false) { - start = dirs.length - 1; - inc = -1; - end = 0; - } + /** + * FileFilter for general files + */ + static class ReadableFileFilter implements FileFilter { + + public boolean accept(File f) { + return f.canRead(); + } + } + + /** + * FileFilter for image types (helper class for getFile) + */ + static class ImageFileFilter implements FileFilter { + + public boolean accept(File f) { + return (classForFilename(f.getName()) == CLASS_IMAGE); + } + } + + /** + * FileFilter for text types (helper class for getFile) + */ + static class TextFileFilter implements FileFilter { + + public boolean accept(File f) { + return (classForFilename(f.getName()) == CLASS_TEXT); + } + } - for (int i = start; i != end; i += inc) { - try { - f = getFile(dirs[i]+fn, n); - } catch (FileOpException e) { - f = null; - } - if (f != null) { - return f; - } - } - throw new FileOpException("Unable to find file: "+fn); - } + /** + * FileFilter for svg types (helper class for getFile). + * + */ + static class SVGFileFilter implements FileFilter { + + public boolean accept(File f) { + return (classForFilename(f.getName()) == CLASS_SVG); + } + } - /** - * get the number of files in a directory - * (almost the same as getFileVariant) - * returns 0 in case of problems - */ - public int getNumFilesVariant(String[] dirs, String fn, boolean fwd) throws FileOpException { - util.dprintln(4, "getNumFilesVariant ("+dirs+", "+fn+")"); + /** + * Factory for FileFilters (image or text). + * + * @param fileClass + * @return + */ + public static FileFilter filterForClass(int fileClass) { + if (fileClass == CLASS_IMAGE) { + return new ImageFileFilter(); + } + if (fileClass == CLASS_TEXT) { + return new TextFileFilter(); + } + if (fileClass == CLASS_SVG) { + return new SVGFileFilter(); + } + return null; + } - int nf = 0; - int start = 0; - int inc = 1; - int end = dirs.length; - if (fwd == false) { - start = dirs.length - 1; - inc = -1; - end = 0; - } + /** + * Factory for DocuDirents based on file class. + * + * Returns an ImageFileset, TextFile or SVGFile. baseDirs and scalext are + * only for ImageFilesets. + * + * @param fileClass + * @param file + * @param hints + * optional additional parameters + * @return + */ + public static DocuDirent fileForClass(int fileClass, File file, Map<Integer,Object> hints) { + // what class of file do we have? + if (fileClass == CLASS_IMAGE) { + // image file + return new ImageFileset(file, hints); + } else if (fileClass == CLASS_TEXT) { + // text file + return new TextFile(file); + } else if (fileClass == CLASS_SVG) { + // text file + return new SVGFile(file); + } + return null; + } - for (int i = start; i != end; i += inc) { - try { - nf = getNumFiles(dirs[i]+fn); - } catch (FileOpException e) { - nf = 0; - } - if (nf > 0) { - return nf; - } - } - return 0; - } + /** + * Filters a list of Files through a FileFilter. + * + * @param files + * @param filter + * @return + */ + public static File[] listFiles(File[] files, FileFilter filter) { + if (files == null) { + return null; + } + File[] ff = new File[files.length]; + int ffi = 0; + for (int i = 0; i < files.length; i++) { + if (filter.accept(files[i])) { + ff[ffi] = files[i]; + ffi++; + } + } + File[] fff = new File[ffi]; + System.arraycopy(ff, 0, fff, 0, ffi); + return fff; + } - /** - * FileFilter for image types (helper class for getFile) - */ - private class ImgFileFilter implements FileFilter { - - public boolean accept(File f) { - if (f.isFile()) { - return (mimeForFile(f) != null); - } else { - return false; - } - } - } + /** + * Creates a new hints Map with the given first element. + * + * @param type + * @param value + * @return + */ + public static Map<Integer, Object> newHints(Integer type, Object value) { + Map<Integer, Object> m = new HashMap<Integer, Object>(); + if (type != null) { + m.put(type, value); + } + return m; + } }