From b64012b1845b4fe56b37d59f859bc863e98825df Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 18 Jan 2022 10:21:38 +0100 Subject: [PATCH] Move file system utils to Argeo Commons --- .../src/org/argeo/cli/jcr/JcrSync.java | 2 +- .../ext/test/org/argeo/fs/FsUtilsTest.java | 2 + .../org/argeo/fs/BasicSyncFileVisitor.java | 164 ------------------ .../src/org/argeo/fs/FsUtils.java | 58 ------- .../src/org/argeo/fs/package-info.java | 2 - .../src/org/argeo/slc/cli/fs/FileSync.java | 2 +- .../src/org/argeo/slc/cli/fs/PathSync.java | 2 +- .../org/argeo/slc/cli/fs/SyncFileVisitor.java | 2 +- .../src/org/argeo/sync/SyncException.java | 18 -- .../src/org/argeo/sync/SyncResult.java | 101 ----------- .../src/org/argeo/sync/package-info.java | 2 - 11 files changed, 6 insertions(+), 349 deletions(-) delete mode 100644 org.argeo.slc.runtime/src/org/argeo/fs/BasicSyncFileVisitor.java delete mode 100644 org.argeo.slc.runtime/src/org/argeo/fs/FsUtils.java delete mode 100644 org.argeo.slc.runtime/src/org/argeo/fs/package-info.java delete mode 100644 org.argeo.slc.runtime/src/org/argeo/sync/SyncException.java delete mode 100644 org.argeo.slc.runtime/src/org/argeo/sync/SyncResult.java delete mode 100644 org.argeo.slc.runtime/src/org/argeo/sync/package-info.java diff --git a/org.argeo.slc.jcr/src/org/argeo/cli/jcr/JcrSync.java b/org.argeo.slc.jcr/src/org/argeo/cli/jcr/JcrSync.java index 53ea25940..1bbce108a 100644 --- a/org.argeo.slc.jcr/src/org/argeo/cli/jcr/JcrSync.java +++ b/org.argeo.slc.jcr/src/org/argeo/cli/jcr/JcrSync.java @@ -25,7 +25,7 @@ import org.argeo.cms.cli.CommandRuntimeException; import org.argeo.cms.cli.DescribedCommand; import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory; import org.argeo.jcr.JcrUtils; -import org.argeo.sync.SyncResult; +import org.argeo.util.SyncResult; public class JcrSync implements DescribedCommand> { public final static String DEFAULT_LOCALFS_CONFIG = "repository-localfs.xml"; diff --git a/org.argeo.slc.runtime/ext/test/org/argeo/fs/FsUtilsTest.java b/org.argeo.slc.runtime/ext/test/org/argeo/fs/FsUtilsTest.java index 793216b1d..587efd7ab 100644 --- a/org.argeo.slc.runtime/ext/test/org/argeo/fs/FsUtilsTest.java +++ b/org.argeo.slc.runtime/ext/test/org/argeo/fs/FsUtilsTest.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import org.argeo.util.FsUtils; + /** {@link FsUtils} tests. */ public class FsUtilsTest { final static String FILE00 = "file00"; diff --git a/org.argeo.slc.runtime/src/org/argeo/fs/BasicSyncFileVisitor.java b/org.argeo.slc.runtime/src/org/argeo/fs/BasicSyncFileVisitor.java deleted file mode 100644 index 03bac592c..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/fs/BasicSyncFileVisitor.java +++ /dev/null @@ -1,164 +0,0 @@ -package org.argeo.fs; - -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.nio.file.attribute.FileTime; - -import org.argeo.sync.SyncResult; - -/** Synchronises two directory structures. */ -public class BasicSyncFileVisitor extends SimpleFileVisitor { - // TODO make it configurable - private boolean trace = false; - - private final Path sourceBasePath; - private final Path targetBasePath; - private final boolean delete; - private final boolean recursive; - - private SyncResult syncResult = new SyncResult<>(); - - public BasicSyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) { - this.sourceBasePath = sourceBasePath; - this.targetBasePath = targetBasePath; - this.delete = delete; - this.recursive = recursive; - } - - @Override - public FileVisitResult preVisitDirectory(Path sourceDir, BasicFileAttributes attrs) throws IOException { - if (!recursive && !sourceDir.equals(sourceBasePath)) - return FileVisitResult.SKIP_SUBTREE; - Path targetDir = toTargetPath(sourceDir); - Files.createDirectories(targetDir); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path sourceDir, IOException exc) throws IOException { - if (delete) { - Path targetDir = toTargetPath(sourceDir); - for (Path targetPath : Files.newDirectoryStream(targetDir)) { - Path sourcePath = sourceDir.resolve(targetPath.getFileName()); - if (!Files.exists(sourcePath)) { - try { - FsUtils.delete(targetPath); - deleted(targetPath); - } catch (Exception e) { - deleteFailed(targetPath, exc); - } - } - } - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path sourceFile, BasicFileAttributes attrs) throws IOException { - Path targetFile = toTargetPath(sourceFile); - try { - if (!Files.exists(targetFile)) { - Files.copy(sourceFile, targetFile); - added(sourceFile, targetFile); - } else { - if (shouldOverwrite(sourceFile, targetFile)) { - Files.copy(sourceFile, targetFile, StandardCopyOption.REPLACE_EXISTING); - } - } - } catch (Exception e) { - copyFailed(sourceFile, targetFile, e); - } - return FileVisitResult.CONTINUE; - } - - protected boolean shouldOverwrite(Path sourceFile, Path targetFile) throws IOException { - long sourceSize = Files.size(sourceFile); - long targetSize = Files.size(targetFile); - if (sourceSize != targetSize) { - return true; - } - FileTime sourceLastModif = Files.getLastModifiedTime(sourceFile); - FileTime targetLastModif = Files.getLastModifiedTime(targetFile); - if (sourceLastModif.compareTo(targetLastModif) > 0) - return true; - return shouldOverwriteLaterSameSize(sourceFile, targetFile); - } - - protected boolean shouldOverwriteLaterSameSize(Path sourceFile, Path targetFile) { - return false; - } - -// @Override -// public FileVisitResult visitFileFailed(Path sourceFile, IOException exc) throws IOException { -// error("Cannot sync " + sourceFile, exc); -// return FileVisitResult.CONTINUE; -// } - - private Path toTargetPath(Path sourcePath) { - Path relativePath = sourceBasePath.relativize(sourcePath); - Path targetPath = targetBasePath.resolve(relativePath.toString()); - return targetPath; - } - - public Path getSourceBasePath() { - return sourceBasePath; - } - - public Path getTargetBasePath() { - return targetBasePath; - } - - protected void added(Path sourcePath, Path targetPath) { - syncResult.getAdded().add(targetPath); - if (isTraceEnabled()) - trace("Added " + sourcePath + " as " + targetPath); - } - - protected void modified(Path sourcePath, Path targetPath) { - syncResult.getModified().add(targetPath); - if (isTraceEnabled()) - trace("Overwritten from " + sourcePath + " to " + targetPath); - } - - protected void copyFailed(Path sourcePath, Path targetPath, Exception e) { - syncResult.addError(sourcePath, targetPath, e); - if (isTraceEnabled()) - error("Cannot copy " + sourcePath + " to " + targetPath, e); - } - - protected void deleted(Path targetPath) { - syncResult.getDeleted().add(targetPath); - if (isTraceEnabled()) - trace("Deleted " + targetPath); - } - - protected void deleteFailed(Path targetPath, Exception e) { - syncResult.addError(null, targetPath, e); - if (isTraceEnabled()) - error("Cannot delete " + targetPath, e); - } - - /** Log error. */ - protected void error(Object obj, Throwable e) { - System.err.println(obj); - e.printStackTrace(); - } - - protected boolean isTraceEnabled() { - return trace; - } - - protected void trace(Object obj) { - System.out.println(obj); - } - - public SyncResult getSyncResult() { - return syncResult; - } - -} diff --git a/org.argeo.slc.runtime/src/org/argeo/fs/FsUtils.java b/org.argeo.slc.runtime/src/org/argeo/fs/FsUtils.java deleted file mode 100644 index c96f56ed2..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/fs/FsUtils.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.argeo.fs; - -import java.io.IOException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; - -/** Utilities around the standard Java file abstractions. */ -public class FsUtils { - /** Sync a source path with a target path. */ - public static void sync(Path sourceBasePath, Path targetBasePath) { - sync(sourceBasePath, targetBasePath, false); - } - - /** Sync a source path with a target path. */ - public static void sync(Path sourceBasePath, Path targetBasePath, boolean delete) { - sync(new BasicSyncFileVisitor(sourceBasePath, targetBasePath, delete, true)); - } - - public static void sync(BasicSyncFileVisitor syncFileVisitor) { - try { - Files.walkFileTree(syncFileVisitor.getSourceBasePath(), syncFileVisitor); - } catch (Exception e) { - throw new RuntimeException("Cannot sync " + syncFileVisitor.getSourceBasePath() + " with " - + syncFileVisitor.getTargetBasePath(), e); - } - } - - /** Deletes this path, recursively if needed. */ - public static void delete(Path path) { - try { - Files.walkFileTree(path, new SimpleFileVisitor() { - @Override - public FileVisitResult postVisitDirectory(Path directory, IOException e) throws IOException { - if (e != null) - throw e; - Files.delete(directory); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - throw new RuntimeException("Cannot delete " + path, e); - } - } - - /** Singleton. */ - private FsUtils() { - } - -} diff --git a/org.argeo.slc.runtime/src/org/argeo/fs/package-info.java b/org.argeo.slc.runtime/src/org/argeo/fs/package-info.java deleted file mode 100644 index ea2de9ed6..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/fs/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Generic file system utilities. */ -package org.argeo.fs; \ No newline at end of file diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FileSync.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FileSync.java index 308f04953..6b8cbfa72 100644 --- a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FileSync.java +++ b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FileSync.java @@ -11,7 +11,7 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.argeo.cms.cli.CommandArgsException; import org.argeo.cms.cli.DescribedCommand; -import org.argeo.sync.SyncResult; +import org.argeo.util.SyncResult; public class FileSync implements DescribedCommand> { final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build(); diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/PathSync.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/PathSync.java index e687d5689..abd0a20d5 100644 --- a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/PathSync.java +++ b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/PathSync.java @@ -8,7 +8,7 @@ import java.nio.file.Paths; import java.nio.file.spi.FileSystemProvider; import java.util.concurrent.Callable; -import org.argeo.sync.SyncResult; +import org.argeo.util.SyncResult; /** Synchronises two paths. */ public class PathSync implements Callable> { diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/SyncFileVisitor.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/SyncFileVisitor.java index 4d696eea2..712ec5f6b 100644 --- a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/SyncFileVisitor.java +++ b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/SyncFileVisitor.java @@ -3,7 +3,7 @@ package org.argeo.slc.cli.fs; import java.nio.file.Path; import org.argeo.api.cms.CmsLog; -import org.argeo.fs.BasicSyncFileVisitor; +import org.argeo.util.BasicSyncFileVisitor; /** Synchronises two directory structures. */ public class SyncFileVisitor extends BasicSyncFileVisitor { diff --git a/org.argeo.slc.runtime/src/org/argeo/sync/SyncException.java b/org.argeo.slc.runtime/src/org/argeo/sync/SyncException.java deleted file mode 100644 index 89bf869a2..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/sync/SyncException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.argeo.sync; - -/** Commons exception for sync */ -public class SyncException extends RuntimeException { - private static final long serialVersionUID = -3371314343580218538L; - - public SyncException(String message) { - super(message); - } - - public SyncException(String message, Throwable cause) { - super(message, cause); - } - - public SyncException(Object source, Object target, Throwable cause) { - super("Cannot sync from " + source + " to " + target, cause); - } -} diff --git a/org.argeo.slc.runtime/src/org/argeo/sync/SyncResult.java b/org.argeo.slc.runtime/src/org/argeo/sync/SyncResult.java deleted file mode 100644 index 6d12ada4a..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/sync/SyncResult.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.argeo.sync; - -import java.time.Instant; -import java.util.Set; -import java.util.TreeSet; - -/** Describes what happendend during a sync operation. */ -public class SyncResult { - private final Set added = new TreeSet<>(); - private final Set modified = new TreeSet<>(); - private final Set deleted = new TreeSet<>(); - private final Set errors = new TreeSet<>(); - - public Set getAdded() { - return added; - } - - public Set getModified() { - return modified; - } - - public Set getDeleted() { - return deleted; - } - - public Set getErrors() { - return errors; - } - - public void addError(T sourcePath, T targetPath, Exception e) { - Error error = new Error(sourcePath, targetPath, e); - errors.add(error); - } - - public boolean noModification() { - return modified.isEmpty() && deleted.isEmpty() && added.isEmpty(); - } - - @Override - public String toString() { - if (noModification()) - return "No modification."; - StringBuffer sb = new StringBuffer(); - for (T p : modified) - sb.append("MOD ").append(p).append('\n'); - for (T p : deleted) - sb.append("DEL ").append(p).append('\n'); - for (T p : added) - sb.append("ADD ").append(p).append('\n'); - for (Error error : errors) - sb.append(error).append('\n'); - return sb.toString(); - } - - public class Error implements Comparable { - private final T sourcePath;// if null this is a failed delete - private final T targetPath; - private final Exception exception; - private final Instant timestamp = Instant.now(); - - public Error(T sourcePath, T targetPath, Exception e) { - super(); - this.sourcePath = sourcePath; - this.targetPath = targetPath; - this.exception = e; - } - - public T getSourcePath() { - return sourcePath; - } - - public T getTargetPath() { - return targetPath; - } - - public Exception getException() { - return exception; - } - - public Instant getTimestamp() { - return timestamp; - } - - @Override - public int compareTo(Error o) { - return timestamp.compareTo(o.timestamp); - } - - @Override - public int hashCode() { - return timestamp.hashCode(); - } - - @Override - public String toString() { - return "ERR " + timestamp + (sourcePath == null ? "Deletion failed" : "Copy failed " + sourcePath) + " " - + targetPath + " " + exception.getMessage(); - } - - } -} diff --git a/org.argeo.slc.runtime/src/org/argeo/sync/package-info.java b/org.argeo.slc.runtime/src/org/argeo/sync/package-info.java deleted file mode 100644 index c5e9da0f6..000000000 --- a/org.argeo.slc.runtime/src/org/argeo/sync/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Synchrnoisation related utilities. */ -package org.argeo.sync; \ No newline at end of file -- 2.30.2