private static SyncPatch diffSync(MetaFile fileOwner, MetaFile other, MetaFile file) throws SynchronizationException { if (fileOwner.getTime() > other.getTime()) { return new SyncPatch(file, null); } else if (fileOwner.getTime() < other.getTime()) { return new SyncPatch(null, file.getName()); } else { throw new SynchronizationException("The same time for conflicted directories"); } }
// private stuff // ============================================================================================= private static SyncPatch recurSync(MetaFile first, MetaFile second, String hashFunc) throws SynchronizationException, IOException { if (first.isFile()) { if (first.getSize() == second.getSize()) { InputStream fis = first.getInputStream(); InputStream sis = second.getInputStream(); if (hashFunc == null) { if (FileUtils.isEqual(fis, sis)) { return null; } } else { byte[] hash1 = first.getHash(hashFunc); byte[] hash2 = second.getHash(hashFunc); if ((hash1 == null) && (hash2 == null) || ((hash1 == null) || (hash2 == null)) && (HashManager.getHashManager().getCalculator(hashFunc) == null)) { if (FileUtils.isEqual(fis, sis)) { return null; } } if (hash1 == null) { hash1 = HashManager.getHashManager().getCalculator(hashFunc).calculate(fis); } if (hash2 == null) { hash2 = HashManager.getHashManager().getCalculator(hashFunc).calculate(sis); } if (Arrays.equals(hash1, hash2)) { return null; } } } if (first.getTime() > second.getTime()) { return new SyncPatch(first, second.getName()); } else if (first.getTime() < second.getTime()) { return new SyncPatch(second, first.getName()); } else { throw new SynchronizationException("The same time for conflicted files"); } } else { // directories Set<SyncPatch> syncs = new HashSet<>(); boolean same = true; Set<String> remained = new HashSet<>(second.getFiles().keySet()); for (String name : first.getFiles().keySet()) { if (remained.remove(name)) { // if file exist in second directory MetaFile fc = first.getFiles().get(name); MetaFile sc = second.getFiles().get(name); // if the one is file and the other is directory if (fc.isFile() && !sc.isFile() || !fc.isFile() && sc.isFile()) { same = false; syncs.add(new SyncPatch(getMaster(fc, sc), null)); } else { // both files or directories exist SyncPatch si = recurSync(fc, sc, hashFunc); if (si != null) { syncs.add(si); } } } else { // file exist only in first directory same = false; syncs.add(diffSync(first, second, first.getFiles().get(name))); } } if (!remained.isEmpty()) { same = false; for (String name : remained) { syncs.add(diffSync(second, first, second.getFiles().get(name))); } } if (same) { if (syncs.isEmpty()) { return null; } else { return new SyncPatch(first, second.getName(), syncs); } } else { if (first.getTime() >= second.getTime()) { return new SyncPatch(first, second.getName(), syncs); } else { return new SyncPatch(second, first.getName(), syncs); } } } }