Mercurial > dive4elements > river
view flys-backend/src/main/java/de/intevation/flys/utils/FileTools.java @ 1216:f8b5c37f15e4
Fixes for the HYK parser
flys-backend/trunk@2342 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sun, 17 Jul 2011 10:00:13 +0000 |
parents | cc88db4a5b34 |
children |
line wrap: on
line source
package de.intevation.flys.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; import java.util.Stack; import java.util.List; import java.util.Set; import java.util.HashSet; import java.util.ArrayList; import org.apache.log4j.Logger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class FileTools { private static Logger log = Logger.getLogger(FileTools.class); public static final String DIGEST = System.getProperty("flys.backend.file.cmp.digest", "MD5"); private FileTools() { } public static File repair(File file) { file = file.getAbsoluteFile(); if (file.exists()) { return file; } Stack<String> parts = new Stack<String>(); File curr = file; while (curr != null) { String name = curr.getName(); if (name.length() > 0) { parts.push(curr.getName()); } curr = curr.getParentFile(); } curr = null; OUTER: while (!parts.isEmpty()) { String f = parts.pop(); log.debug("fixing: '" + f + "'"); if (curr == null) { // XXX: Not totaly correct because there // more than one root on none unix systems. for (File root: File.listRoots()) { File [] files = root.listFiles(); if (files == null) { log.warn("cannot list '" + root); continue; } for (File candidate: files) { if (candidate.getName().equalsIgnoreCase(f)) { curr = new File(root, candidate.getName()); continue OUTER; } } } break; } else { File [] files = curr.listFiles(); if (files == null) { log.warn("cannot list: '" + curr + "'"); return file; } for (File candidate: files) { if (candidate.getName().equalsIgnoreCase(f)) { curr = new File(curr, candidate.getName()); continue OUTER; } } curr = null; break; } } if (curr == null) { log.warn("cannot repair path '" + file + "'"); return file; } return curr; } public static class HashedFile implements Comparable<HashedFile> { protected File file; protected long length; protected byte [] hash; public HashedFile(File file) { this.file = file; length = file.length(); } public File getFile() { return file; } protected byte [] getHash() { if (hash == null) { InputStream in = null; try { in = new FileInputStream(file); MessageDigest digest = MessageDigest.getInstance(DIGEST); byte [] buf = new byte[40*1024]; int r; while ((r = in.read(buf)) >= 0) { digest.update(buf, 0, r); } hash = digest.digest(); } catch (IOException ioe) { log.error(ioe); hash = new byte[0]; } catch (NoSuchAlgorithmException nsae) { log.error(nsae); hash = new byte[0]; } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { log.error(ioe); } } } } return hash; } @Override public int compareTo(HashedFile other) { if (length < other.length) return -1; if (length > other.length) return +1; return compare(getHash(), other.getHash()); } private static int compare(byte [] a, byte [] b) { if (a.length < b.length) return -1; if (a.length > b.length) return +1; for (int i = 0; i < a.length; ++i) { int x = a[i] & 0xff; int y = b[i] & 0xff; if (x < y) return -1; if (x > y) return +1; } return 0; } @Override public boolean equals(Object other) { return other instanceof HashedFile && ((HashedFile)other).compareTo(this) == 0; } @Override public int hashCode() { return (int)(length ^ (length >>> 32)); } } // class HashedFile public static List<File> uniqueFiles(List<File> files) { Set<HashedFile> set = new HashSet<HashedFile>(); for (File file: files) { if (!set.add(new HashedFile(file))) { log.warn("file '" + file + "' is a duplicate."); } } ArrayList<File> out = new ArrayList<File>(set.size()); for (HashedFile hf: set) { out.add(hf.file); } return out; } public interface FileVisitor { boolean visit(File file); } // Visitor public static void walkTree(File root, FileVisitor visitor) { Stack<File> stack = new Stack<File>(); stack.push(root); while (!stack.isEmpty()) { File current = stack.pop(); if (!visitor.visit(current)) break; if (current.isDirectory()) { File [] subs = current.listFiles(); if (subs != null) { for (File f: subs) { stack.push(f); } } } } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :