Beispiel #1
0
  //  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);
        }
      }
    }
  }