package com.constellio.data.io.concurrent.filesystem; import java.io.File; import java.util.Arrays; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.constellio.data.io.concurrent.data.DataWithVersion; public class AtomicFileSystemUtils { private static Logger LOGGER = LoggerFactory.getLogger(AtomicFileSystemUtils.class); /** * This function is not thread safe. * @param master * @param slave * @return */ public static boolean sync(AtomicFileSystem master, AtomicFileSystem slave){ return sync(master, slave, (String[])null); } public static boolean sync(AtomicFileSystem master, AtomicFileSystem slave, String... excludePathRegex){ return sync(File.separator, master, slave, excludePathRegex); } public static boolean sync( String path, AtomicFileSystem master, AtomicFileSystem slave, String... excludePathRegex) { if (matchWithExclusion(path, excludePathRegex)) return true; if (master.isDirectory(path)){ boolean isSynced = true; if (slave.exists(path) && !slave.isDirectory(path)){ slave.delete(path, null); isSynced = false; } else if (!slave.exists(path)){ slave.mkdirs(path); isSynced = false; } List<String> slaveSubPathes = slave.list(path); for (String subPath: master.list(path)){ isSynced &= sync(subPath, master, slave, excludePathRegex); slaveSubPathes.remove(subPath); } for (String remainPath: slaveSubPathes){ if (matchWithExclusion(remainPath, excludePathRegex)) continue; isSynced = false; remove(slave, remainPath); } return isSynced; } else { boolean isSynced; if (slave.isDirectory(path)){ LOGGER.info("delete a directory in the slave:" + path); slave.delete(path, null); } DataWithVersion masterData = master.readData(path); byte[] masterBinaryData = masterData.getData(); if (slave.exists(path)){ DataWithVersion slaveData = slave.readData(path); isSynced = Arrays.equals(slaveData.getData(), masterBinaryData); } else { isSynced = false; } if (!isSynced){ slave.writeData(path, new DataWithVersion(masterBinaryData, null)); } return isSynced; } } private static boolean matchWithExclusion(String path, String... excludePathRegex) { if (excludePathRegex != null) for (String exclude: excludePathRegex){ if (path.matches(exclude)) return true; } return false; } private static void remove(AtomicFileSystem slave, String remainPath) { if (slave.isDirectory(remainPath)){ for (String path: slave.list(remainPath)){ remove(slave, path); } } slave.delete(remainPath, null); } }