sascha@177: package de.intevation.flys.utils; sascha@177: sascha@177: import java.io.File; sascha@1206: import java.io.IOException; sascha@1206: import java.io.InputStream; sascha@1206: import java.io.FileInputStream; sascha@177: sascha@177: import java.util.Stack; sascha@1206: import java.util.List; sascha@1206: import java.util.Set; sascha@1206: import java.util.HashSet; sascha@1206: import java.util.ArrayList; sascha@177: sascha@177: import org.apache.log4j.Logger; sascha@177: sascha@1206: import java.security.MessageDigest; sascha@1206: import java.security.NoSuchAlgorithmException; sascha@1206: sascha@177: public class FileTools sascha@177: { sascha@177: private static Logger log = Logger.getLogger(FileTools.class); sascha@177: sascha@1206: public static final String DIGEST = sascha@1206: System.getProperty("flys.backend.file.cmp.digest", "MD5"); sascha@1206: sascha@177: private FileTools() { sascha@177: } sascha@177: sascha@177: public static File repair(File file) { sascha@177: file = file.getAbsoluteFile(); sascha@177: if (file.exists()) { sascha@177: return file; sascha@177: } sascha@177: Stack parts = new Stack(); sascha@177: File curr = file; sascha@177: while (curr != null) { sascha@177: String name = curr.getName(); sascha@177: if (name.length() > 0) { sascha@177: parts.push(curr.getName()); sascha@177: } sascha@177: curr = curr.getParentFile(); sascha@177: } sascha@177: sascha@177: curr = null; sascha@177: OUTER: while (!parts.isEmpty()) { sascha@177: String f = parts.pop(); sascha@177: log.debug("fixing: '" + f + "'"); sascha@177: if (curr == null) { sascha@177: // XXX: Not totaly correct because there sascha@177: // more than one root on none unix systems. sascha@177: for (File root: File.listRoots()) { sascha@177: File [] files = root.listFiles(); sascha@177: if (files == null) { sascha@177: log.warn("cannot list '" + root); sascha@177: continue; sascha@177: } sascha@177: for (File candidate: files) { sascha@177: if (candidate.getName().equalsIgnoreCase(f)) { sascha@177: curr = new File(root, candidate.getName()); sascha@177: continue OUTER; sascha@177: } sascha@177: } sascha@177: } sascha@177: break; sascha@177: } sascha@177: else { sascha@177: File [] files = curr.listFiles(); sascha@177: if (files == null) { sascha@177: log.warn("cannot list: '" + curr + "'"); sascha@177: return file; sascha@177: } sascha@177: for (File candidate: files) { sascha@177: if (candidate.getName().equalsIgnoreCase(f)) { sascha@177: curr = new File(curr, candidate.getName()); sascha@177: continue OUTER; sascha@177: } sascha@177: } sascha@177: curr = null; sascha@177: break; sascha@177: } sascha@177: } sascha@177: sascha@177: if (curr == null) { sascha@177: log.warn("cannot repair path '" + file + "'"); sascha@177: return file; sascha@177: } sascha@177: sascha@177: return curr; sascha@177: } sascha@1206: sascha@1206: public static class HashedFile sascha@1206: implements Comparable sascha@1206: { sascha@1206: protected File file; sascha@1206: protected long length; sascha@1206: protected byte [] hash; sascha@1206: sascha@1206: public HashedFile(File file) { sascha@1206: this.file = file; sascha@1206: length = file.length(); sascha@1206: } sascha@1206: sascha@1206: public File getFile() { sascha@1206: return file; sascha@1206: } sascha@1206: sascha@1206: protected byte [] getHash() { sascha@1206: if (hash == null) { sascha@1206: InputStream in = null; sascha@1206: sascha@1206: try { sascha@1206: in = new FileInputStream(file); sascha@1206: sascha@1206: MessageDigest digest = MessageDigest.getInstance(DIGEST); sascha@1206: sascha@1206: byte [] buf = new byte[40*1024]; sascha@1206: int r; sascha@1206: sascha@1206: while ((r = in.read(buf)) >= 0) { sascha@1206: digest.update(buf, 0, r); sascha@1206: } sascha@1206: sascha@1206: hash = digest.digest(); sascha@1206: } sascha@1206: catch (IOException ioe) { sascha@1206: log.error(ioe); sascha@1206: hash = new byte[0]; sascha@1206: } sascha@1206: catch (NoSuchAlgorithmException nsae) { sascha@1206: log.error(nsae); sascha@1206: hash = new byte[0]; sascha@1206: } sascha@1206: finally { sascha@1206: if (in != null) { sascha@1206: try { sascha@1206: in.close(); sascha@1206: } sascha@1206: catch (IOException ioe) { sascha@1206: log.error(ioe); sascha@1206: } sascha@1206: } sascha@1206: } sascha@1206: } sascha@1206: return hash; sascha@1206: } sascha@1206: sascha@1206: @Override sascha@1206: public int compareTo(HashedFile other) { sascha@1206: if (length < other.length) return -1; sascha@1206: if (length > other.length) return +1; sascha@1207: return compare(getHash(), other.getHash()); sascha@1206: } sascha@1206: sascha@1206: private static int compare(byte [] a, byte [] b) { sascha@1206: if (a.length < b.length) return -1; sascha@1206: if (a.length > b.length) return +1; sascha@1206: for (int i = 0; i < a.length; ++i) { sascha@1206: int x = a[i] & 0xff; sascha@1206: int y = b[i] & 0xff; sascha@1206: if (x < y) return -1; sascha@1206: if (x > y) return +1; sascha@1206: } sascha@1206: return 0; sascha@1206: } sascha@1206: sascha@1206: @Override sascha@1206: public boolean equals(Object other) { sascha@1206: return other instanceof HashedFile sascha@1206: && ((HashedFile)other).compareTo(this) == 0; sascha@1206: } sascha@1206: sascha@1206: @Override sascha@1206: public int hashCode() { sascha@1206: return (int)(length ^ (length >>> 32)); sascha@1206: } sascha@1206: } // class HashedFile sascha@1206: sascha@1206: public static List uniqueFiles(List files) { sascha@1206: sascha@1206: Set set = new HashSet(); sascha@1206: sascha@1206: for (File file: files) { sascha@1206: if (!set.add(new HashedFile(file))) { sascha@1206: log.warn("file '" + file + "' is a duplicate."); sascha@1206: } sascha@1206: } sascha@1206: sascha@1206: ArrayList out = new ArrayList(set.size()); sascha@1206: for (HashedFile hf: set) { sascha@1206: out.add(hf.file); sascha@1206: } sascha@1206: sascha@1206: return out; sascha@1206: } sascha@177: } sascha@177: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :