Dispatch code to CMS and Suite
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 16 May 2022 05:21:53 +0000 (07:21 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 16 May 2022 05:21:53 +0000 (07:21 +0200)
20 files changed:
org.argeo.slc.runtime/ext/test/org/argeo/fs/FsUtilsTest.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandArgsException.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandRuntimeException.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandsCli.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/DescribedCommand.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/HelpCommand.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FileSync.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FsCommands.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/PathSync.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/SyncFileVisitor.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/package-info.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/package-info.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/cli/posix/Echo.java
org.argeo.slc.runtime/src/org/argeo/slc/cli/posix/PosixCommands.java
org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailMigration.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailUtils.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/runtime/ArgeoCli.java
org.argeo.slc.runtime/src/org/argeo/slc/sync/BasicSyncFileVisitor.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/sync/FsSyncUtils.java [deleted file]
org.argeo.slc.runtime/src/org/argeo/slc/sync/SyncResult.java [deleted file]

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
deleted file mode 100644 (file)
index 5d31f4a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.argeo.fs;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import org.argeo.slc.sync.FsSyncUtils;
-
-/** {@link FsUtils} tests. */
-public class FsUtilsTest {
-       final static String FILE00 = "file00";
-       final static String FILE01 = "file01";
-       final static String SUB_DIR = "subDir";
-
-       public void testDelete() throws IOException {
-               Path dir = createDir00();
-               assert Files.exists(dir);
-               FsSyncUtils.delete(dir);
-               assert !Files.exists(dir);
-       }
-
-       public void testSync() throws IOException {
-               Path source = createDir00();
-               Path target = Files.createTempDirectory(getClass().getName());
-               FsSyncUtils.sync(source, target);
-               assert Files.exists(target.resolve(FILE00));
-               assert Files.exists(target.resolve(SUB_DIR));
-               assert Files.exists(target.resolve(SUB_DIR + File.separator + FILE01));
-               FsSyncUtils.delete(source.resolve(SUB_DIR));
-               FsSyncUtils.sync(source, target, true);
-               assert Files.exists(target.resolve(FILE00));
-               assert !Files.exists(target.resolve(SUB_DIR));
-               assert !Files.exists(target.resolve(SUB_DIR + File.separator + FILE01));
-
-               // clean up
-               FsSyncUtils.delete(source);
-               FsSyncUtils.delete(target);
-
-       }
-
-       Path createDir00() throws IOException {
-               Path base = Files.createTempDirectory(getClass().getName());
-               base.toFile().deleteOnExit();
-               Files.createFile(base.resolve(FILE00)).toFile().deleteOnExit();
-               Path subDir = Files.createDirectories(base.resolve(SUB_DIR));
-               subDir.toFile().deleteOnExit();
-               Files.createFile(subDir.resolve(FILE01)).toFile().deleteOnExit();
-               return base;
-       }
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandArgsException.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandArgsException.java
deleted file mode 100644 (file)
index 4d4d759..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.argeo.slc.cli;
-
-public class CommandArgsException extends IllegalArgumentException {
-       private static final long serialVersionUID = -7271050747105253935L;
-       private String commandName;
-       private volatile CommandsCli commandsCli;
-
-       public CommandArgsException(Exception cause) {
-               super(cause.getMessage(), cause);
-       }
-
-       public CommandArgsException(String message) {
-               super(message);
-       }
-
-       public String getCommandName() {
-               return commandName;
-       }
-
-       public void setCommandName(String commandName) {
-               this.commandName = commandName;
-       }
-
-       public CommandsCli getCommandsCli() {
-               return commandsCli;
-       }
-
-       public void setCommandsCli(CommandsCli commandsCli) {
-               this.commandsCli = commandsCli;
-       }
-
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandRuntimeException.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandRuntimeException.java
deleted file mode 100644 (file)
index 9072544..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.argeo.slc.cli;
-
-import java.util.List;
-
-/** {@link RuntimeException} referring during a command run. */
-public class CommandRuntimeException extends RuntimeException {
-       private static final long serialVersionUID = 5595999301269377128L;
-
-       private final DescribedCommand<?> command;
-       private final List<String> arguments;
-
-       public CommandRuntimeException(Throwable e, DescribedCommand<?> command, List<String> arguments) {
-               this(null, e, command, arguments);
-       }
-
-       public CommandRuntimeException(String message, DescribedCommand<?> command, List<String> arguments) {
-               this(message, null, command, arguments);
-       }
-
-       public CommandRuntimeException(String message, Throwable e, DescribedCommand<?> command, List<String> arguments) {
-               super(message == null ? "(" + command.getClass().getName() + " " + arguments.toString() + ")"
-                               : message + " (" + command.getClass().getName() + " " + arguments.toString() + ")", e);
-               this.command = command;
-               this.arguments = arguments;
-       }
-
-       public DescribedCommand<?> getCommand() {
-               return command;
-       }
-
-       public List<String> getArguments() {
-               return arguments;
-       }
-
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandsCli.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/CommandsCli.java
deleted file mode 100644 (file)
index 5146fb7..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.argeo.slc.cli;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** Base class for a CLI managing sub commands. */
-public abstract class CommandsCli implements DescribedCommand<Object> {
-       public final static String HELP = "help";
-
-       private final String commandName;
-       private Map<String, Function<List<String>, ?>> commands = new TreeMap<>();
-
-       protected final Options options = new Options();
-
-       public CommandsCli(String commandName) {
-               this.commandName = commandName;
-       }
-
-       @Override
-       public Object apply(List<String> args) {
-               String cmd = null;
-               List<String> newArgs = new ArrayList<>();
-               try {
-                       CommandLineParser clParser = new DefaultParser();
-                       CommandLine commonCl = clParser.parse(getOptions(), args.toArray(new String[args.size()]), true);
-                       List<String> leftOvers = commonCl.getArgList();
-                       for (String arg : leftOvers) {
-                               if (!arg.startsWith("-") && cmd == null) {
-                                       cmd = arg;
-                               } else {
-                                       newArgs.add(arg);
-                               }
-                       }
-               } catch (ParseException e) {
-                       CommandArgsException cae = new CommandArgsException(e);
-                       throw cae;
-               }
-
-               Function<List<String>, ?> function = cmd != null ? getCommand(cmd) : getDefaultCommand();
-               if (function == null)
-                       throw new IllegalArgumentException("Uknown command " + cmd);
-               try {
-                       return function.apply(newArgs).toString();
-               } catch (CommandArgsException e) {
-                       if (e.getCommandName() == null) {
-                               e.setCommandName(cmd);
-                               e.setCommandsCli(this);
-                       }
-                       throw e;
-               } catch (IllegalArgumentException e) {
-                       CommandArgsException cae = new CommandArgsException(e);
-                       cae.setCommandName(cmd);
-                       throw cae;
-               }
-       }
-
-       @Override
-       public Options getOptions() {
-               return options;
-       }
-
-       protected void addCommand(String cmd, Function<List<String>, ?> function) {
-               commands.put(cmd, function);
-
-       }
-
-       @Override
-       public String getUsage() {
-               return "[command]";
-       }
-
-       protected void addCommandsCli(CommandsCli commandsCli) {
-               addCommand(commandsCli.getCommandName(), commandsCli);
-               commandsCli.addCommand(HELP, new HelpCommand(this, commandsCli));
-       }
-
-       public String getCommandName() {
-               return commandName;
-       }
-
-       public Set<String> getSubCommands() {
-               return commands.keySet();
-       }
-
-       public Function<List<String>, ?> getCommand(String command) {
-               return commands.get(command);
-       }
-
-       public HelpCommand getHelpCommand() {
-               return (HelpCommand) getCommand(HELP);
-       }
-
-       public Function<List<String>, String> getDefaultCommand() {
-               return getHelpCommand();
-       }
-
-       /** In order to implement quickly a main method. */
-       public static void mainImpl(CommandsCli cli, String[] args) {
-               try {
-                       cli.addCommand(CommandsCli.HELP, new HelpCommand(null, cli));
-                       Object output = cli.apply(Arrays.asList(args));
-                       System.out.println(output);
-                       System.exit(0);
-               } catch (CommandArgsException e) {
-                       System.err.println("Wrong arguments " + Arrays.toString(args) + ": " + e.getMessage());
-                       if (e.getCommandName() != null) {
-                               StringWriter out = new StringWriter();
-                               HelpCommand.printHelp(e.getCommandsCli(), e.getCommandName(), out);
-                               System.err.println(out.toString());
-                       } else {
-                               e.printStackTrace();
-                       }
-                       System.exit(1);
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       System.exit(1);
-               }
-       }
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/DescribedCommand.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/DescribedCommand.java
deleted file mode 100644 (file)
index fc1b139..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.argeo.slc.cli;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.DefaultParser;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-
-/** A command that can be described. */
-public interface DescribedCommand<T> extends Function<List<String>, T> {
-       default Options getOptions() {
-               return new Options();
-       }
-
-       String getDescription();
-
-       default String getUsage() {
-               return null;
-       }
-
-       default String getExamples() {
-               return null;
-       }
-
-       default CommandLine toCommandLine(List<String> args) {
-               try {
-                       DefaultParser parser = new DefaultParser();
-                       return parser.parse(getOptions(), args.toArray(new String[args.size()]));
-               } catch (ParseException e) {
-                       throw new CommandArgsException(e);
-               }
-       }
-
-       /** In order to implement quickly a main method. */
-       public static void mainImpl(DescribedCommand<?> command, String[] args) {
-               try {
-                       Object output = command.apply(Arrays.asList(args));
-                       System.out.println(output);
-                       System.exit(0);
-               } catch (IllegalArgumentException e) {
-                       StringWriter out = new StringWriter();
-                       HelpCommand.printHelp(command, out);
-                       System.err.println(out.toString());
-                       System.exit(1);
-               } catch (Exception e) {
-                       e.printStackTrace();
-                       System.exit(1);
-               }
-       }
-
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/HelpCommand.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/HelpCommand.java
deleted file mode 100644 (file)
index 8400d05..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package org.argeo.slc.cli;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-import java.util.function.Function;
-
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-
-/** A special command that can describe {@link DescribedCommand}. */
-public class HelpCommand implements DescribedCommand<String> {
-       private CommandsCli commandsCli;
-       private CommandsCli parentCommandsCli;
-
-       // Help formatting
-       private static int helpWidth = 80;
-       private static int helpLeftPad = 4;
-       private static int helpDescPad = 20;
-
-       public HelpCommand(CommandsCli parentCommandsCli, CommandsCli commandsCli) {
-               super();
-               this.parentCommandsCli = parentCommandsCli;
-               this.commandsCli = commandsCli;
-       }
-
-       @Override
-       public String apply(List<String> args) {
-               StringWriter out = new StringWriter();
-
-               if (args.size() == 0) {// overview
-                       printHelp(commandsCli, out);
-               } else {
-                       String cmd = args.get(0);
-                       Function<List<String>, ?> function = commandsCli.getCommand(cmd);
-                       if (function == null)
-                               return "Command " + cmd + " not found.";
-                       Options options;
-                       String examples;
-                       DescribedCommand<?> command = null;
-                       if (function instanceof DescribedCommand) {
-                               command = (DescribedCommand<?>) function;
-                               options = command.getOptions();
-                               examples = command.getExamples();
-                       } else {
-                               options = new Options();
-                               examples = null;
-                       }
-                       String description = getShortDescription(function);
-                       String commandCall = getCommandUsage(cmd, command);
-                       HelpFormatter formatter = new HelpFormatter();
-                       formatter.printHelp(new PrintWriter(out), helpWidth, commandCall, description, options, helpLeftPad,
-                                       helpDescPad, examples, false);
-               }
-               return out.toString();
-       }
-
-       private static String getShortDescription(Function<List<String>, ?> function) {
-               if (function instanceof DescribedCommand) {
-                       return ((DescribedCommand<?>) function).getDescription();
-               } else {
-                       return function.toString();
-               }
-       }
-
-       public String getCommandUsage(String cmd, DescribedCommand<?> command) {
-               String commandCall = getCommandCall(commandsCli) + " " + cmd;
-               assert command != null;
-               if (command != null && command.getUsage() != null) {
-                       commandCall = commandCall + " " + command.getUsage();
-               }
-               return commandCall;
-       }
-
-       @Override
-       public String getDescription() {
-               return "Shows this help or describes a command";
-       }
-
-       @Override
-       public String getUsage() {
-               return "[command]";
-       }
-
-       public CommandsCli getParentCommandsCli() {
-               return parentCommandsCli;
-       }
-
-       protected String getCommandCall(CommandsCli commandsCli) {
-               HelpCommand hc = commandsCli.getHelpCommand();
-               if (hc.getParentCommandsCli() != null) {
-                       return getCommandCall(hc.getParentCommandsCli()) + " " + commandsCli.getCommandName();
-               } else {
-                       return commandsCli.getCommandName();
-               }
-       }
-
-       public static void printHelp(DescribedCommand<?> command, StringWriter out) {
-               String usage = "java " + command.getClass().getName()
-                               + (command.getUsage() != null ? " " + command.getUsage() : "");
-               HelpFormatter formatter = new HelpFormatter();
-               formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
-                               helpLeftPad, helpDescPad, command.getExamples(), false);
-
-       }
-
-       public static void printHelp(CommandsCli commandsCli, String commandName, StringWriter out) {
-               DescribedCommand<?> command = (DescribedCommand<?>) commandsCli.getCommand(commandName);
-               String usage = commandsCli.getHelpCommand().getCommandUsage(commandName, command);
-               HelpFormatter formatter = new HelpFormatter();
-               formatter.printHelp(new PrintWriter(out), helpWidth, usage, command.getDescription(), command.getOptions(),
-                               helpLeftPad, helpDescPad, command.getExamples(), false);
-
-       }
-
-       public static void printHelp(CommandsCli commandsCli, StringWriter out) {
-               out.append(commandsCli.getDescription()).append('\n');
-               String leftPad = spaces(helpLeftPad);
-               for (String cmd : commandsCli.getSubCommands()) {
-                       Function<List<String>, ?> function = commandsCli.getCommand(cmd);
-                       assert function != null;
-                       out.append(leftPad);
-                       out.append(cmd);
-                       // TODO deal with long commands
-                       out.append(spaces(helpDescPad - cmd.length()));
-                       out.append(getShortDescription(function));
-                       out.append('\n');
-               }
-       }
-
-       private static String spaces(int count) {
-               // Java 11
-               // return " ".repeat(count);
-               if (count <= 0)
-                       return "";
-               else {
-                       StringBuilder sb = new StringBuilder(count);
-                       for (int i = 0; i < count; i++)
-                               sb.append(' ');
-                       return sb.toString();
-               }
-       }
-}
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
deleted file mode 100644 (file)
index dfff27c..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.argeo.slc.cli.fs;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.Options;
-import org.argeo.slc.cli.CommandArgsException;
-import org.argeo.slc.cli.DescribedCommand;
-import org.argeo.slc.sync.SyncResult;
-
-public class FileSync implements DescribedCommand<SyncResult<Path>> {
-       final static Option deleteOption = Option.builder().longOpt("delete").desc("delete from target").build();
-       final static Option recursiveOption = Option.builder("r").longOpt("recursive").desc("recurse into directories")
-                       .build();
-       final static Option progressOption = Option.builder().longOpt("progress").hasArg(false).desc("show progress")
-                       .build();
-
-       @Override
-       public SyncResult<Path> apply(List<String> t) {
-               try {
-                       CommandLine line = toCommandLine(t);
-                       List<String> remaining = line.getArgList();
-                       if (remaining.size() == 0) {
-                               throw new CommandArgsException("There must be at least one argument");
-                       }
-                       URI sourceUri = new URI(remaining.get(0));
-                       URI targetUri;
-                       if (remaining.size() == 1) {
-                               targetUri = Paths.get(System.getProperty("user.dir")).toUri();
-                       } else {
-                               targetUri = new URI(remaining.get(1));
-                       }
-                       boolean delete = line.hasOption(deleteOption.getLongOpt());
-                       boolean recursive = line.hasOption(recursiveOption.getLongOpt());
-                       PathSync pathSync = new PathSync(sourceUri, targetUri, delete, recursive);
-                       return pathSync.call();
-               } catch (URISyntaxException e) {
-                       throw new CommandArgsException(e);
-               }
-       }
-
-       @Override
-       public Options getOptions() {
-               Options options = new Options();
-               options.addOption(recursiveOption);
-               options.addOption(deleteOption);
-               options.addOption(progressOption);
-               return options;
-       }
-
-       @Override
-       public String getUsage() {
-               return "[source URI] [target URI]";
-       }
-
-       public static void main(String[] args) {
-               DescribedCommand.mainImpl(new FileSync(), args);
-//             Options options = new Options();
-//             options.addOption("r", "recursive", false, "recurse into directories");
-//             options.addOption(Option.builder().longOpt("progress").hasArg(false).desc("show progress").build());
-//
-//             CommandLineParser parser = new DefaultParser();
-//             try {
-//                     CommandLine line = parser.parse(options, args);
-//                     List<String> remaining = line.getArgList();
-//                     if (remaining.size() == 0) {
-//                             System.err.println("There must be at least one argument");
-//                             printHelp(options);
-//                             System.exit(1);
-//                     }
-//                     URI sourceUri = new URI(remaining.get(0));
-//                     URI targetUri;
-//                     if (remaining.size() == 1) {
-//                             targetUri = Paths.get(System.getProperty("user.dir")).toUri();
-//                     } else {
-//                             targetUri = new URI(remaining.get(1));
-//                     }
-//                     PathSync pathSync = new PathSync(sourceUri, targetUri);
-//                     pathSync.run();
-//             } catch (Exception exp) {
-//                     exp.printStackTrace();
-//                     printHelp(options);
-//                     System.exit(1);
-//             }
-       }
-
-//     public static void printHelp(Options options) {
-//             HelpFormatter formatter = new HelpFormatter();
-//             formatter.printHelp("sync SRC [DEST]", options, true);
-//     }
-
-       @Override
-       public String getDescription() {
-               return "Synchronises files";
-       }
-
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FsCommands.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/FsCommands.java
deleted file mode 100644 (file)
index cab3c1e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.argeo.slc.cli.fs;
-
-import org.argeo.slc.cli.CommandsCli;
-
-/** File utilities. */
-public class FsCommands extends CommandsCli {
-
-       public FsCommands(String commandName) {
-               super(commandName);
-               addCommand("sync", new FileSync());
-       }
-
-       @Override
-       public String getDescription() {
-               return "Utilities around files and file systems";
-       }
-
-}
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
deleted file mode 100644 (file)
index 844af01..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.argeo.slc.cli.fs;
-
-import java.net.URI;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.spi.FileSystemProvider;
-import java.util.concurrent.Callable;
-
-import org.argeo.slc.sync.SyncResult;
-
-/** Synchronises two paths. */
-public class PathSync implements Callable<SyncResult<Path>> {
-       private final URI sourceUri, targetUri;
-       private final boolean delete;
-       private final boolean recursive;
-
-       public PathSync(URI sourceUri, URI targetUri) {
-               this(sourceUri, targetUri, false, false);
-       }
-
-       public PathSync(URI sourceUri, URI targetUri, boolean delete, boolean recursive) {
-               this.sourceUri = sourceUri;
-               this.targetUri = targetUri;
-               this.delete = delete;
-               this.recursive = recursive;
-       }
-
-       @Override
-       public SyncResult<Path> call() {
-               try {
-                       Path sourceBasePath = createPath(sourceUri);
-                       Path targetBasePath = createPath(targetUri);
-                       SyncFileVisitor syncFileVisitor = new SyncFileVisitor(sourceBasePath, targetBasePath, delete, recursive);
-                       Files.walkFileTree(sourceBasePath, syncFileVisitor);
-                       return syncFileVisitor.getSyncResult();
-               } catch (Exception e) {
-                       throw new IllegalStateException("Cannot sync " + sourceUri + " to " + targetUri, e);
-               }
-       }
-
-       private Path createPath(URI uri) {
-               Path path;
-               if (uri.getScheme() == null) {
-                       path = Paths.get(uri.getPath());
-               } else if (uri.getScheme().equals("file")) {
-                       FileSystemProvider fsProvider = FileSystems.getDefault().provider();
-                       path = fsProvider.getPath(uri);
-               } else if (uri.getScheme().equals("davex")) {
-                       throw new UnsupportedOperationException();
-//                     FileSystemProvider fsProvider = new DavexFsProvider();
-//                     path = fsProvider.getPath(uri);
-//             } else if (uri.getScheme().equals("sftp")) {
-//                     Sftp sftp = new Sftp(uri);
-//                     path = sftp.getBasePath();
-               } else
-                       throw new IllegalArgumentException("URI scheme not supported for " + uri);
-               return path;
-       }
-}
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
deleted file mode 100644 (file)
index 43af111..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.argeo.slc.cli.fs;
-
-import java.lang.System.Logger;
-import java.lang.System.Logger.Level;
-import java.nio.file.Path;
-import java.util.Objects;
-
-import org.argeo.slc.sync.BasicSyncFileVisitor;
-
-/** Synchronises two directory structures. */
-public class SyncFileVisitor extends BasicSyncFileVisitor {
-       private final static Logger logger = System.getLogger(SyncFileVisitor.class.getName());
-
-       public SyncFileVisitor(Path sourceBasePath, Path targetBasePath, boolean delete, boolean recursive) {
-               super(sourceBasePath, targetBasePath, delete, recursive);
-       }
-
-       @Override
-       protected void error(Object obj, Throwable e) {
-               logger.log(Level.ERROR, Objects.toString(obj), e);
-       }
-
-       @Override
-       protected boolean isTraceEnabled() {
-               return logger.isLoggable(Level.TRACE);
-       }
-
-       @Override
-       protected void trace(Object obj) {
-               logger.log(Level.TRACE, Objects.toString(obj));
-       }
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/package-info.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/fs/package-info.java
deleted file mode 100644 (file)
index 8c61d93..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** File system CLI commands. */
-package org.argeo.slc.cli.fs;
\ No newline at end of file
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/cli/package-info.java b/org.argeo.slc.runtime/src/org/argeo/slc/cli/package-info.java
deleted file mode 100644 (file)
index 0216a28..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/** Command line API. */
-package org.argeo.slc.cli;
\ No newline at end of file
index a479e96d197399d8712bc69cf262a17b59c0e740..d773760bc23809e3e9522264d478e5578be8ab3e 100644 (file)
@@ -5,7 +5,7 @@ import java.util.List;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
 import org.apache.commons.cli.Options;
-import org.argeo.slc.cli.DescribedCommand;
+import org.argeo.cms.cli.DescribedCommand;
 
 public class Echo implements DescribedCommand<String> {
 
index 67544108dedc0edaf17ff1b5f1f69ceb31096fab..bb5920e55ba259ee9d533ad5213bb36f1ff9eef4 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.slc.cli.posix;
 
-import org.argeo.slc.cli.CommandsCli;
+import org.argeo.cms.cli.CommandsCli;
 
 /** POSIX commands. */
 public class PosixCommands extends CommandsCli {
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailMigration.java b/org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailMigration.java
deleted file mode 100644 (file)
index 7826cae..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-package org.argeo.slc.mail;
-
-import static java.lang.System.Logger.Level.DEBUG;
-import static java.lang.System.Logger.Level.ERROR;
-import static org.argeo.slc.mail.EmailUtils.describe;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.System.Logger;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.time.Instant;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.Properties;
-
-import javax.mail.FetchProfile;
-import javax.mail.Folder;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Session;
-import javax.mail.Store;
-import javax.mail.URLName;
-import javax.mail.internet.InternetHeaders;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.search.HeaderTerm;
-import javax.mail.util.SharedFileInputStream;
-
-import com.sun.mail.imap.IMAPFolder;
-import com.sun.mail.mbox.MboxFolder;
-import com.sun.mail.mbox.MboxMessage;
-
-/** Migrates emails from one storage to the another one. */
-public class EmailMigration {
-       private final static Logger logger = System.getLogger(EmailMigration.class.getName());
-
-//     private String targetBaseDir;
-
-       private String sourceServer;
-       private String sourceUsername;
-       private String sourcePassword;
-
-       private String targetServer;
-       private String targetUsername;
-       private String targetPassword;
-
-       public void process() throws MessagingException, IOException {
-//             Path baseDir = Paths.get(targetBaseDir).resolve(sourceUsername).resolve("mbox");
-
-               Store sourceStore = null;
-               try {
-                       Properties sourceProperties = System.getProperties();
-                       sourceProperties.setProperty("mail.store.protocol", "imaps");
-
-                       Session sourceSession = Session.getInstance(sourceProperties, null);
-                       // session.setDebug(true);
-                       sourceStore = sourceSession.getStore("imaps");
-                       sourceStore.connect(sourceServer, sourceUsername, sourcePassword);
-
-                       Folder defaultFolder = sourceStore.getDefaultFolder();
-//                     migrateFolders(baseDir, defaultFolder);
-
-                       // Always start with Inbox
-//                     Folder inboxFolder = sourceStore.getFolder(EmailUtils.INBOX);
-//                     migrateFolder(baseDir, inboxFolder);
-
-                       Properties targetProperties = System.getProperties();
-                       targetProperties.setProperty("mail.imap.starttls.enable", "true");
-                       targetProperties.setProperty("mail.imap.auth", "true");
-
-                       Session targetSession = Session.getInstance(targetProperties, null);
-                       // session.setDebug(true);
-                       Store targetStore = targetSession.getStore("imap");
-                       targetStore.connect(targetServer, targetUsername, targetPassword);
-
-//                     Folder targetFolder = targetStore.getFolder(EmailUtils.INBOX);
-//                     logger.log(DEBUG, "Source message count " + inboxFolder.getMessageCount());
-//                     logger.log(DEBUG, "Target message count " + targetFolder.getMessageCount());
-
-                       migrateFolders(defaultFolder, targetStore);
-               } finally {
-                       if (sourceStore != null)
-                               sourceStore.close();
-
-               }
-       }
-
-       protected void migrateFolders(Folder sourceFolder, Store targetStore) throws MessagingException, IOException {
-               folders: for (Folder folder : sourceFolder.list()) {
-                       String folderName = folder.getName();
-
-                       String folderFullName = folder.getFullName();
-
-                       // GMail specific
-                       if (folderFullName.equals("[Gmail]")) {
-                               migrateFolders(folder, targetStore);
-                               continue folders;
-                       }
-                       if (folderFullName.startsWith("[Gmail]")) {
-                               // Make it configurable
-                               switch (folderName) {
-                               case "All Mail":
-                               case "Important":
-                               case "Spam":
-                                       continue folders;
-                               default:
-                                       // does nothing
-                               }
-                               folderFullName = folder.getName();
-                       }
-
-                       int messageCount = (folder.getType() & Folder.HOLDS_MESSAGES) != 0 ? folder.getMessageCount() : 0;
-                       boolean hasSubFolders = (folder.getType() & Folder.HOLDS_FOLDERS) != 0 ? folder.list().length != 0 : false;
-                       Folder targetFolder;
-                       if (hasSubFolders) {// has sub-folders
-                               if (messageCount == 0) {
-                                       targetFolder = targetStore.getFolder(folderFullName);
-                                       if (!targetFolder.exists()) {
-                                               targetFolder.create(Folder.HOLDS_FOLDERS);
-                                               logger.log(DEBUG, "Created HOLDS_FOLDERS folder " + targetFolder.getFullName());
-                                       }
-                               } else {// also has messages
-                                       Folder parentFolder = targetStore.getFolder(folderFullName);
-                                       if (!parentFolder.exists()) {
-                                               parentFolder.create(Folder.HOLDS_FOLDERS);
-                                               logger.log(DEBUG, "Created HOLDS_FOLDERS folder " + parentFolder.getFullName());
-                                       }
-                                       String miscFullName = folderFullName + "/_Misc";
-                                       targetFolder = targetStore.getFolder(miscFullName);
-                                       if (!targetFolder.exists()) {
-                                               targetFolder.create(Folder.HOLDS_MESSAGES);
-                                               logger.log(DEBUG, "Created HOLDS_MESSAGES folder " + targetFolder.getFullName());
-                                       }
-                               }
-                       } else {// no sub-folders
-                               if (messageCount == 0) { // empty
-                                       logger.log(DEBUG, "Skip empty folder " + folderFullName);
-                                       continue folders;
-                               }
-                               targetFolder = targetStore.getFolder(folderFullName);
-                               if (!targetFolder.exists()) {
-                                       targetFolder.create(Folder.HOLDS_MESSAGES);
-                                       logger.log(DEBUG, "Created HOLDS_MESSAGES folder " + targetFolder.getFullName());
-                               }
-                       }
-
-                       if (messageCount != 0) {
-
-                               targetFolder.open(Folder.READ_WRITE);
-                               try {
-                                       long begin = System.currentTimeMillis();
-                                       folder.open(Folder.READ_ONLY);
-                                       migrateFolder(folder, targetFolder);
-                                       long duration = System.currentTimeMillis() - begin;
-                                       logger.log(DEBUG, folderFullName + " - Migration of " + messageCount + " messages took "
-                                                       + (duration / 1000) + " s (" + (duration / messageCount) + " ms per message)");
-                               } finally {
-                                       folder.close();
-                                       targetFolder.close();
-                               }
-                       }
-
-                       // recursive
-                       if (hasSubFolders) {
-                               migrateFolders(folder, targetStore);
-                       }
-               }
-       }
-
-       protected void migrateFoldersToFs(Path baseDir, Folder sourceFolder) throws MessagingException, IOException {
-               folders: for (Folder folder : sourceFolder.list()) {
-                       String folderName = folder.getName();
-
-                       if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
-                               // Make it configurable
-                               switch (folderName) {
-                               case "All Mail":
-                               case "Important":
-                                       continue folders;
-                               default:
-                                       // doe nothing
-                               }
-                               migrateFolderToFs(baseDir, folder);
-                       }
-                       if ((folder.getType() & Folder.HOLDS_FOLDERS) != 0) {
-                               migrateFoldersToFs(baseDir.resolve(folder.getName()), folder);
-                       }
-               }
-       }
-
-       protected void migrateFolderToFs(Path baseDir, Folder sourceFolder) throws MessagingException, IOException {
-
-               String folderName = sourceFolder.getName();
-               sourceFolder.open(Folder.READ_ONLY);
-
-               Folder targetFolder = null;
-               try {
-                       int messageCount = sourceFolder.getMessageCount();
-                       logger.log(DEBUG, folderName + " - Message count : " + messageCount);
-                       if (messageCount == 0)
-                               return;
-//                     logger.log(DEBUG, folderName + " - Unread Messages : " + sourceFolder.getUnreadMessageCount());
-
-                       boolean saveAsFiles = false;
-
-                       if (saveAsFiles) {
-                               Message messages[] = sourceFolder.getMessages();
-
-                               for (int i = 0; i < messages.length; ++i) {
-//                                     logger.log(DEBUG, "MESSAGE #" + (i + 1) + ":");
-                                       Message msg = messages[i];
-//                                     String from = "unknown";
-//                                     if (msg.getReplyTo().length >= 1) {
-//                                             from = msg.getReplyTo()[0].toString();
-//                                     } else if (msg.getFrom().length >= 1) {
-//                                             from = msg.getFrom()[0].toString();
-//                                     }
-                                       String subject = msg.getSubject();
-                                       Instant sentDate = msg.getSentDate().toInstant();
-//                                     logger.log(DEBUG, "Saving ... " + subject + " from " + from + " (" + sentDate + ")");
-                                       String fileName = sentDate + "  " + subject;
-                                       Path file = baseDir.resolve(fileName);
-                                       savePartsAsFiles(msg.getContent(), file);
-                               }
-                       } 
-                       else {
-                               long begin = System.currentTimeMillis();
-                               targetFolder = openMboxTargetFolder(sourceFolder, baseDir);
-                               migrateFolder(sourceFolder, targetFolder);
-                               long duration = System.currentTimeMillis() - begin;
-                               logger.log(DEBUG, folderName + " - Migration of " + messageCount + " messages took " + (duration / 1000)
-                                               + " s (" + (duration / messageCount) + " ms per message)");
-                       }
-               } finally {
-                       sourceFolder.close();
-                       if (targetFolder != null)
-                               targetFolder.close();
-               }
-       }
-
-       protected Folder migrateFolder(Folder sourceFolder, Folder targetFolder) throws MessagingException, IOException {
-               String folderName = targetFolder.getName();
-
-               int lastSourceNumber;
-               int currentTargetMessageCount = targetFolder.getMessageCount();
-               if (currentTargetMessageCount != 0) {
-                       MimeMessage lastTargetMessage = (MimeMessage) targetFolder.getMessage(currentTargetMessageCount);
-                       logger.log(DEBUG, folderName + " - Last target message " + describe(lastTargetMessage));
-                       Date lastTargetSent = lastTargetMessage.getReceivedDate();
-                       Message[] lastSourceMessage = sourceFolder
-                                       .search(new HeaderTerm(EmailUtils.MESSAGE_ID, lastTargetMessage.getMessageID()));
-                       if (lastSourceMessage.length == 0)
-                               throw new IllegalStateException("No message found with message ID " + lastTargetMessage.getMessageID());
-                       if (lastSourceMessage.length != 1) {
-                               for (Message msg : lastSourceMessage) {
-                                       logger.log(ERROR, "Message " + describe(msg));
-
-                               }
-                               throw new IllegalStateException(
-                                               lastSourceMessage.length + " messages found with received date " + lastTargetSent.toInstant());
-                       }
-                       lastSourceNumber = lastSourceMessage[0].getMessageNumber();
-               } else {
-                       lastSourceNumber = 0;
-               }
-               logger.log(DEBUG, folderName + " - Last source message number " + lastSourceNumber);
-
-               int countToRetrieve = sourceFolder.getMessageCount() - lastSourceNumber;
-
-               FetchProfile fetchProfile = new FetchProfile();
-               fetchProfile.add(FetchProfile.Item.FLAGS);
-               fetchProfile.add(FetchProfile.Item.ENVELOPE);
-               fetchProfile.add(FetchProfile.Item.CONTENT_INFO);
-               fetchProfile.add(FetchProfile.Item.SIZE);
-               if (sourceFolder instanceof IMAPFolder) {
-                       // IMAPFolder sourceImapFolder = (IMAPFolder) sourceFolder;
-                       fetchProfile.add(IMAPFolder.FetchProfileItem.HEADERS);
-                       fetchProfile.add(IMAPFolder.FetchProfileItem.MESSAGE);
-               }
-
-               int batchSize = 100;
-               int batchCount = countToRetrieve / batchSize;
-               if (countToRetrieve % batchSize != 0)
-                       batchCount = batchCount + 1;
-               // int batchCount = 2; // for testing
-               for (int i = 0; i < batchCount; i++) {
-                       long begin = System.currentTimeMillis();
-
-                       int start = lastSourceNumber + i * batchSize + 1;
-                       int end = lastSourceNumber + (i + 1) * batchSize;
-                       if (end >= (lastSourceNumber + countToRetrieve + 1))
-                               end = lastSourceNumber + countToRetrieve;
-                       Message[] sourceMessages = sourceFolder.getMessages(start, end);
-                       sourceFolder.fetch(sourceMessages, fetchProfile);
-                       // targetFolder.appendMessages(sourceMessages);
-                       // sourceFolder.copyMessages(sourceMessages,targetFolder);
-
-                       copyMessages(sourceMessages, targetFolder);
-//                     copyMessagesToMbox(sourceMessages, targetFolder);
-
-                       String describeLast = describe(sourceMessages[sourceMessages.length - 1]);
-
-//             if (i % 10 == 9) {
-                       // free memory from fetched messages
-                       sourceFolder.close();
-                       targetFolder.close();
-
-                       sourceFolder.open(Folder.READ_ONLY);
-                       targetFolder.open(Folder.READ_WRITE);
-//                     logger.log(DEBUG, "Open/close folder in order to free memory");
-//             }
-
-                       long duration = System.currentTimeMillis() - begin;
-                       logger.log(DEBUG, folderName + " - batch " + i + " took " + (duration / 1000) + " s, "
-                                       + (duration / (end - start + 1)) + " ms per message. Last message " + describeLast);
-               }
-
-               return targetFolder;
-       }
-
-       protected Folder openMboxTargetFolder(Folder sourceFolder, Path baseDir) throws MessagingException, IOException {
-               String folderName = sourceFolder.getName();
-               if (sourceFolder.getName().equals(EmailUtils.INBOX_UPPER_CASE))
-                       folderName = EmailUtils.INBOX;// Inbox
-
-               Path targetDir = baseDir;// .resolve("mbox");
-               Files.createDirectories(targetDir);
-               Path targetPath;
-               if (((sourceFolder.getType() & Folder.HOLDS_FOLDERS) != 0) && sourceFolder.list().length != 0) {
-                       Path dir = targetDir.resolve(folderName);
-                       Files.createDirectories(dir);
-                       targetPath = dir.resolve("_Misc");
-               } else {
-                       targetPath = targetDir.resolve(folderName);
-               }
-               if (!Files.exists(targetPath))
-                       Files.createFile(targetPath);
-               URLName targetUrlName = new URLName("mbox:" + targetPath.toString());
-               Properties targetProperties = new Properties();
-               // targetProperties.setProperty("mail.mime.address.strict", "false");
-               Session targetSession = Session.getDefaultInstance(targetProperties);
-               Folder targetFolder = targetSession.getFolder(targetUrlName);
-               targetFolder.open(Folder.READ_WRITE);
-
-               return targetFolder;
-       }
-
-       protected void copyMessages(Message[] sourceMessages, Folder targetFolder) throws MessagingException {
-               targetFolder.appendMessages(sourceMessages);
-       }
-
-       protected void copyMessagesToMbox(Message[] sourceMessages, Folder targetFolder)
-                       throws MessagingException, IOException {
-               Message[] targetMessages = new Message[sourceMessages.length];
-               for (int j = 0; j < sourceMessages.length; j++) {
-                       MimeMessage sourceMm = (MimeMessage) sourceMessages[j];
-                       InternetHeaders ih = new InternetHeaders();
-                       for (Enumeration<String> e = sourceMm.getAllHeaderLines(); e.hasMoreElements();) {
-                               ih.addHeaderLine(e.nextElement());
-                       }
-                       Path tmpFileSource = Files.createTempFile("argeo-mbox-source", ".txt");
-                       Path tmpFileTarget = Files.createTempFile("argeo-mbox-target", ".txt");
-                       Files.copy(sourceMm.getRawInputStream(), tmpFileSource, StandardCopyOption.REPLACE_EXISTING);
-
-                       // we use ISO_8859_1 because it is more robust than US_ASCII with regard to
-                       // missing characters
-                       try (BufferedReader reader = Files.newBufferedReader(tmpFileSource, StandardCharsets.ISO_8859_1);
-                                       BufferedWriter writer = Files.newBufferedWriter(tmpFileTarget, StandardCharsets.ISO_8859_1);) {
-                               int lineNumber = 0;
-                               String line = null;
-                               try {
-                                       while ((line = reader.readLine()) != null) {
-                                               lineNumber++;
-                                               if (line.startsWith("From ")) {
-                                                       writer.write(">" + line);
-                                                       logger.log(DEBUG,
-                                                                       "Fix line " + lineNumber + " in " + EmailUtils.describe(sourceMm) + ": " + line);
-                                               } else {
-                                                       writer.write(line);
-                                               }
-                                               writer.newLine();
-                                       }
-                               } catch (IOException e) {
-                                       logger.log(ERROR, "Error around line " + lineNumber + " of " + tmpFileSource);
-                                       throw e;
-                               }
-                       }
-
-                       MboxMessage mboxMessage = new MboxMessage((MboxFolder) targetFolder, ih,
-                                       new SharedFileInputStream(tmpFileTarget.toFile()), sourceMm.getMessageNumber(),
-                                       EmailUtils.getUnixFrom(sourceMm), true);
-                       targetMessages[j] = mboxMessage;
-
-                       // clean up
-                       Files.delete(tmpFileSource);
-                       Files.delete(tmpFileTarget);
-               }
-               targetFolder.appendMessages(targetMessages);
-
-       }
-
-       /** Save body parts and attachments as plain files. */
-       protected void savePartsAsFiles(Object content, Path fileBase) throws IOException, MessagingException {
-               OutputStream out = null;
-               InputStream in = null;
-               try {
-                       if (content instanceof Multipart) {
-                               Multipart multi = ((Multipart) content);
-                               int parts = multi.getCount();
-                               for (int j = 0; j < parts; ++j) {
-                                       MimeBodyPart part = (MimeBodyPart) multi.getBodyPart(j);
-                                       if (part.getContent() instanceof Multipart) {
-                                               // part-within-a-part, do some recursion...
-                                               savePartsAsFiles(part.getContent(), fileBase);
-                                       } else {
-                                               String extension = "";
-                                               if (part.isMimeType("text/html")) {
-                                                       extension = "html";
-                                               } else {
-                                                       if (part.isMimeType("text/plain")) {
-                                                               extension = "txt";
-                                                       } else {
-                                                               // Try to get the name of the attachment
-                                                               extension = part.getDataHandler().getName();
-                                                       }
-                                               }
-                                               String filename = fileBase + "." + extension;
-                                               System.out.println("... " + filename);
-                                               out = new FileOutputStream(new File(filename));
-                                               in = part.getInputStream();
-                                               int k;
-                                               while ((k = in.read()) != -1) {
-                                                       out.write(k);
-                                               }
-                                       }
-                               }
-                       }
-               } finally {
-                       if (in != null) {
-                               in.close();
-                       }
-                       if (out != null) {
-                               out.flush();
-                               out.close();
-                       }
-               }
-       }
-
-       public void setSourceServer(String sourceServer) {
-               this.sourceServer = sourceServer;
-       }
-
-       public void setSourceUsername(String sourceUsername) {
-               this.sourceUsername = sourceUsername;
-       }
-
-       public void setSourcePassword(String sourcePassword) {
-               this.sourcePassword = sourcePassword;
-       }
-
-       public void setTargetServer(String targetServer) {
-               this.targetServer = targetServer;
-       }
-
-       public void setTargetUsername(String targetUsername) {
-               this.targetUsername = targetUsername;
-       }
-
-       public void setTargetPassword(String targetPassword) {
-               this.targetPassword = targetPassword;
-       }
-
-       public static void main(String args[]) throws Exception {
-               if (args.length < 6)
-                       throw new IllegalArgumentException(
-                                       "usage: <source IMAP server> <source username> <source password> <target IMAP server> <target username> <target password>");
-               String sourceServer = args[0];
-               String sourceUsername = args[1];
-               String sourcePassword = args[2];
-               String targetServer = args[3];
-               String targetUsername = args[4];
-               String targetPassword = args[5];
-
-               EmailMigration emailMigration = new EmailMigration();
-               emailMigration.setSourceServer(sourceServer);
-               emailMigration.setSourceUsername(sourceUsername);
-               emailMigration.setSourcePassword(sourcePassword);
-               emailMigration.setTargetServer(targetServer);
-               emailMigration.setTargetUsername(targetUsername);
-               emailMigration.setTargetPassword(targetPassword);
-
-               emailMigration.process();
-       }
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailUtils.java b/org.argeo.slc.runtime/src/org/argeo/slc/mail/EmailUtils.java
deleted file mode 100644 (file)
index 6965547..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.argeo.slc.mail;
-
-import java.util.Date;
-
-import javax.mail.Address;
-import javax.mail.Flags;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-
-/** Utilities around emails. */
-public class EmailUtils {
-       public final static String INBOX = "Inbox";
-       public final static String INBOX_UPPER_CASE = "INBOX";
-       public final static String MESSAGE_ID = "Message-ID";
-
-       public static String getMessageId(Message msg) {
-               try {
-                       return msg instanceof MimeMessage ? ((MimeMessage) msg).getMessageID() : "<N/A>";
-               } catch (MessagingException e) {
-                       throw new IllegalStateException("Cannot extract message id from " + msg, e);
-               }
-       }
-
-       public static String describe(Message msg) {
-               try {
-                       return "Message " + msg.getMessageNumber() + " " + msg.getSentDate().toInstant() + " " + getMessageId(msg);
-               } catch (MessagingException e) {
-                       throw new IllegalStateException("Cannot describe " + msg, e);
-               }
-       }
-
-       static void setHeadersFromFlags(MimeMessage msg, Flags flags) {
-               try {
-                       StringBuilder status = new StringBuilder();
-                       if (flags.contains(Flags.Flag.SEEN))
-                               status.append('R');
-                       if (!flags.contains(Flags.Flag.RECENT))
-                               status.append('O');
-                       if (status.length() > 0)
-                               msg.setHeader("Status", status.toString());
-                       else
-                               msg.removeHeader("Status");
-
-                       boolean sims = false;
-                       String s = msg.getHeader("X-Status", null);
-                       // is it a SIMS 2.0 format X-Status header?
-                       sims = s != null && s.length() == 4 && s.indexOf('$') >= 0;
-                       //status.setLength(0);
-                       if (flags.contains(Flags.Flag.DELETED))
-                               status.append('D');
-                       else if (sims)
-                               status.append('$');
-                       if (flags.contains(Flags.Flag.FLAGGED))
-                               status.append('F');
-                       else if (sims)
-                               status.append('$');
-                       if (flags.contains(Flags.Flag.ANSWERED))
-                               status.append('A');
-                       else if (sims)
-                               status.append('$');
-                       if (flags.contains(Flags.Flag.DRAFT))
-                               status.append('T');
-                       else if (sims)
-                               status.append('$');
-                       if (status.length() > 0)
-                               msg.setHeader("X-Status", status.toString());
-                       else
-                               msg.removeHeader("X-Status");
-
-                       String[] userFlags = flags.getUserFlags();
-                       if (userFlags.length > 0) {
-                               status.setLength(0);
-                               for (int i = 0; i < userFlags.length; i++)
-                                       status.append(userFlags[i]).append(' ');
-                               status.setLength(status.length() - 1); // smash trailing space
-                               msg.setHeader("X-Keywords", status.toString());
-                       }
-                       if (flags.contains(Flags.Flag.DELETED)) {
-                               s = msg.getHeader("X-Dt-Delete-Time", null);
-                               if (s == null)
-                                       // XXX - should be time
-                                       msg.setHeader("X-Dt-Delete-Time", "1");
-                       }
-               } catch (MessagingException e) {
-                       // ignore it
-               }
-       }
-
-    protected static String getUnixFrom(MimeMessage msg) {
-       Address[] afrom;
-       String from;
-       Date ddate;
-       String date;
-       try {
-           if ((afrom = msg.getFrom()) == null ||
-                   !(afrom[0] instanceof InternetAddress) ||
-                   (from = ((InternetAddress)afrom[0]).getAddress()) == null)
-               from = "UNKNOWN";
-           if ((ddate = msg.getReceivedDate()) == null ||
-                   (ddate = msg.getSentDate()) == null)
-               ddate = new Date();
-       } catch (MessagingException e) {
-           from = "UNKNOWN";
-           ddate = new Date();
-       }
-       date = ddate.toString();
-       // date is of the form "Sat Aug 12 02:30:00 PDT 1995"
-       // need to strip out the timezone
-       return "From " + from + " " +
-               date.substring(0, 20) + date.substring(24);
-    }
-
-       /** Singleton. */
-       private EmailUtils() {
-       }
-}
index 40470fea0437b09b2edda05b7f300ce8e9e1d44e..3e62f575b96b51526388357245dc1c67f1468f81 100644 (file)
@@ -1,8 +1,7 @@
 package org.argeo.slc.runtime;
 
 import org.apache.commons.cli.Option;
-import org.argeo.slc.cli.CommandsCli;
-import org.argeo.slc.cli.fs.FsCommands;
+import org.argeo.cms.cli.CommandsCli;
 import org.argeo.slc.cli.posix.PosixCommands;
 
 /** Argeo command line tools. */
@@ -16,7 +15,7 @@ public class ArgeoCli extends CommandsCli {
                                Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
 
                addCommandsCli(new PosixCommands("posix"));
-               addCommandsCli(new FsCommands("fs"));
+//             addCommandsCli(new FsCommands("fs"));
 //             addCommandsCli(new JcrCommands("jcr"));
        }
 
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/sync/BasicSyncFileVisitor.java b/org.argeo.slc.runtime/src/org/argeo/slc/sync/BasicSyncFileVisitor.java
deleted file mode 100644 (file)
index 066812d..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.argeo.slc.sync;
-
-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;
-
-/** Synchronises two directory structures. */
-public class BasicSyncFileVisitor extends SimpleFileVisitor<Path> {
-       // 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<Path> 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 {
-                                               FsSyncUtils.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<Path> getSyncResult() {
-               return syncResult;
-       }
-
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/sync/FsSyncUtils.java b/org.argeo.slc.runtime/src/org/argeo/slc/sync/FsSyncUtils.java
deleted file mode 100644 (file)
index 4321778..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.argeo.slc.sync;
-
-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;
-
-public class FsSyncUtils {
-       /** 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. Does nothing if the path does not
-        * exist.
-        */
-       public static void delete(Path path) {
-               try {
-                       if (!Files.exists(path))
-                               return;
-                       Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
-                               @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 FsSyncUtils() {
-
-       }
-}
diff --git a/org.argeo.slc.runtime/src/org/argeo/slc/sync/SyncResult.java b/org.argeo.slc.runtime/src/org/argeo/slc/sync/SyncResult.java
deleted file mode 100644 (file)
index 22a2f56..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.argeo.slc.sync;
-
-import java.time.Instant;
-import java.util.Set;
-import java.util.TreeSet;
-
-/** Describes what happendend during a sync operation. */
-public class SyncResult<T> {
-       private final Set<T> added = new TreeSet<>();
-       private final Set<T> modified = new TreeSet<>();
-       private final Set<T> deleted = new TreeSet<>();
-       private final Set<Error> errors = new TreeSet<>();
-
-       public Set<T> getAdded() {
-               return added;
-       }
-
-       public Set<T> getModified() {
-               return modified;
-       }
-
-       public Set<T> getDeleted() {
-               return deleted;
-       }
-
-       public Set<Error> 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<Error> {
-               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();
-               }
-
-       }
-}