BUNDLES = \
org.argeo.slc.api \
org.argeo.slc.factory \
-ext/org.argeo.ext.slf4j
+org.argeo.slc.runtime \
+ext/org.argeo.ext.slf4j \
+ext/org.argeo.ext.equinox.jetty \
BUILD_CLASSPATH_FEDORA = \
/usr/share/java/osgi-core/osgi.core.jar:$\
/usr/share/java/commons-cli.jar:$\
/usr/share/java/commons-exec.jar:$\
-DISTRIBUTION_CLASSPATH = \
-$(SDK_BUILD_BASE)/a2/org.argeo.slc/org.argeo.slc.api.$(MAJOR).$(MINOR).jar:$\
-$(SDK_BUILD_BASE)/a2/org.argeo.slc/org.argeo.slc.factory.$(MAJOR).$(MINOR).jar:$\
-/usr/share/java/bndlib.jar:$\
-/usr/share/java/slf4j-api.jar
-
# TODO relativize from SDK_SRC_BASE
BUILD_BASE = $(SDK_BUILD_BASE)
-distribution: osgi
- $(JVM) -cp $(DISTRIBUTION_CLASSPATH) tp/Make.java
#
#
JVM := /usr/bin/java
JAVADOC := /usr/bin/javadoc
-ECJ_JAR := /usr/share/java/ecj.jar
+ECJ_JAR := $(SDK_BUILD_BASE)/a2/org.argeo.tp.sdk/org.eclipse.jdt.core.compiler.batch.3.28.jar
BND_TOOL := /usr/bin/bnd
WORKSPACE_BNDS := $(shell cd $(SDK_SRC_BASE) && find cnf -name '*.bnd')
-#BND_WORKSPACES := $(foreach bundle, $(BUNDLES), ./$(dir $(bundle)))
BUILD_WORKSPACE_BNDS := $(WORKSPACE_BNDS:%=$(SDK_BUILD_BASE)/%) $(WORKSPACE_BNDS:%=$(SDK_BUILD_BASE)/ext/%)
cnf: $(BUILD_WORKSPACE_BNDS)
A2_BUNDLES = $(BUNDLES:%=$(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/%.$(MAJOR).$(MINOR).jar)
+A2_JARS = $(shell find $(SDK_BUILD_BASE)/a2 -name '*.jar')
+A2_CLASSPATH = $(subst $(space),$(pathsep),$(strip $(A2_JARS)))
+
+
#JAVA_SRCS = $(shell find $(BUNDLE_PREFIX).* -name '*.java')
JAVA_SRCS = $(foreach bundle, $(BUNDLES), $(shell find $(bundle) -name '*.java'))
ECJ_SRCS = $(foreach bundle, $(BUNDLES), $(bundle)/src[-d $(BUILD_BASE)/$(bundle)/bin])
osgi: cnf $(A2_BUNDLES)
mkdir -p $(SDK_BUILD_BASE)/a2/org.argeo.tp
mv $(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/ext/org.argeo.ext.slf4j.$(MAJOR).$(MINOR).jar $(SDK_BUILD_BASE)/a2/org.argeo.tp
+ mv $(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/ext/org.argeo.ext.equinox.jetty.$(MAJOR).$(MINOR).jar $(SDK_BUILD_BASE)/a2/org.argeo.tp.eclipse.equinox
rmdir $(SDK_BUILD_BASE)/a2/$(A2_CATEGORY)/ext
+distribution: bootstrap
+ $(JVM) -cp \
+ $(SDK_BUILD_BASE)/bootstrap/bndlib.jar:$(SDK_BUILD_BASE)/bootstrap/slf4j-api.jar:$(SDK_BUILD_BASE)/org.argeo.slc.api/bin:$(SDK_BUILD_BASE)/org.argeo.slc.factory/bin \
+ tp/Make.java
+
+bootstrap :
+ mkdir -p $(SDK_BUILD_BASE)/bootstrap
+ wget -c -O $(SDK_BUILD_BASE)/bootstrap/ecj.jar https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.28.0/ecj-3.28.0.jar
+ wget -c -O $(SDK_BUILD_BASE)/bootstrap/slf4j-api.jar https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.28/slf4j-api-1.7.28.jar
+ wget -c -O $(SDK_BUILD_BASE)/bootstrap/bndlib.jar https://repo1.maven.org/maven2/biz/aQute/bnd/biz.aQute.bndlib/5.3.0/biz.aQute.bndlib-5.3.0.jar
+ $(JVM) -cp $(SDK_BUILD_BASE)/bootstrap/ecj.jar org.eclipse.jdt.internal.compiler.batch.Main -11 -nowarn -time -cp \
+ $(SDK_BUILD_BASE)/bootstrap/bndlib.jar:$(SDK_BUILD_BASE)/bootstrap/slf4j.jar \
+ org.argeo.slc.api/src[-d $(SDK_BUILD_BASE)/org.argeo.slc.api/bin] \
+ org.argeo.slc.factory/src[-d $(SDK_BUILD_BASE)/org.argeo.slc.factory/bin] \
+
clean:
rm -rf $(BUILD_BASE)/*-compiled
rm -rf $(BUILD_BASE)/cnf
rm -rf $(BUILD_BASE)/ext
rm -rf $(BUILD_BASE)/build
rm -rf $(BUILD_BASE)/deb
+ rm -rf $(BUILD_BASE)/bootstrap
# SDK level
$(SDK_BUILD_BASE)/cnf/%.bnd: cnf/%.bnd
mv $(dir $@)generated/*.jar $(dir $@)bundle.jar
$(BUILD_BASE)/java-compiled : $(JAVA_SRCS)
- $(JVM) -cp $(ECJ_JAR) org.eclipse.jdt.internal.compiler.batch.Main -11 -nowarn -time -cp $(BUILD_CLASSPATH) \
+ $(JVM) -jar $(ECJ_JAR) -11 -nowarn -time -cp $(A2_CLASSPATH) \
$(ECJ_SRCS)
touch $@
space := $(null) #
pathsep := :
-#WITH_LIST := $(subst $(space),$(pathsep),$(strip $(WITH_LIST)))
import java.nio.file.Files;
import java.nio.file.Path;
-import org.argeo.util.FsUtils;
+import org.argeo.slc.sync.FsSyncUtils;
/** {@link FsUtils} tests. */
public class FsUtilsTest {
public void testDelete() throws IOException {
Path dir = createDir00();
assert Files.exists(dir);
- FsUtils.delete(dir);
+ FsSyncUtils.delete(dir);
assert !Files.exists(dir);
}
public void testSync() throws IOException {
Path source = createDir00();
Path target = Files.createTempDirectory(getClass().getName());
- FsUtils.sync(source, target);
+ 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));
- FsUtils.delete(source.resolve(SUB_DIR));
- FsUtils.sync(source, target, true);
+ 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
- FsUtils.delete(source);
- FsUtils.delete(target);
+ FsSyncUtils.delete(source);
+ FsSyncUtils.delete(target);
}
+++ /dev/null
-package org.argeo.slc.cli;
-
-import org.apache.commons.cli.Option;
-import org.argeo.cms.cli.CommandsCli;
-import org.argeo.slc.cli.fs.FsCommands;
-import org.argeo.slc.cli.posix.PosixCommands;
-
-/** Argeo command line tools. */
-public class ArgeoCli extends CommandsCli {
-
- public ArgeoCli(String commandName) {
- super(commandName);
- // Common options
- options.addOption(Option.builder("v").hasArg().argName("verbose").desc("verbosity").build());
- options.addOption(
- Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
-
- addCommandsCli(new PosixCommands("posix"));
- addCommandsCli(new FsCommands("fs"));
-// addCommandsCli(new JcrCommands("jcr"));
- }
-
- @Override
- public String getDescription() {
- return "Argeo command line utilities";
- }
-
- public static void main(String[] args) {
- mainImpl(new ArgeoCli("argeo"), args);
- }
-
-}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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);
+ }
+ }
+}
--- /dev/null
+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);
+ }
+ }
+
+}
--- /dev/null
+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();
+ }
+ }
+}
import org.apache.commons.cli.CommandLine;
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.util.SyncResult;
+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();
package org.argeo.slc.cli.fs;
-import org.argeo.cms.cli.CommandsCli;
+import org.argeo.slc.cli.CommandsCli;
/** File utilities. */
public class FsCommands extends CommandsCli {
import java.nio.file.spi.FileSystemProvider;
import java.util.concurrent.Callable;
-import org.argeo.util.SyncResult;
+import org.argeo.slc.sync.SyncResult;
/** Synchronises two paths. */
public class PathSync implements Callable<SyncResult<Path>> {
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.api.cms.CmsLog;
-import org.argeo.util.BasicSyncFileVisitor;
+import org.argeo.slc.sync.BasicSyncFileVisitor;
/** Synchronises two directory structures. */
public class SyncFileVisitor extends BasicSyncFileVisitor {
- private final static CmsLog log = CmsLog.getLog(SyncFileVisitor.class);
+ 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) {
- log.error(obj, e);
+ logger.log(Level.ERROR, Objects.toString(obj), e);
}
@Override
protected boolean isTraceEnabled() {
- return log.isTraceEnabled();
+ return logger.isLoggable(Level.TRACE);
}
@Override
protected void trace(Object obj) {
- log.trace(obj);
+ logger.log(Level.TRACE, Objects.toString(obj));
}
}
--- /dev/null
+/** Command line API. */
+package org.argeo.slc.cli;
\ No newline at end of file
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
-import org.argeo.cms.cli.DescribedCommand;
+import org.argeo.slc.cli.DescribedCommand;
public class Echo implements DescribedCommand<String> {
package org.argeo.slc.cli.posix;
-import org.argeo.cms.cli.CommandsCli;
+import org.argeo.slc.cli.CommandsCli;
/** POSIX commands. */
public class PosixCommands extends CommandsCli {
import java.util.Map;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.execution.ExecutionContext;
import org.argeo.slc.execution.ExecutionFlow;
import org.argeo.slc.execution.ExecutionFlowDescriptorConverter;
/** Provides the base feature of an execution module manager. */
public abstract class AbstractExecutionModulesManager implements
ExecutionModulesManager {
- private final static CmsLog log = CmsLog
- .getLog(AbstractExecutionModulesManager.class);
// private List<FilteredNotifier> filteredNotifiers = Collections
// .synchronizedList(new ArrayList<FilteredNotifier>());
String moduleName, String moduleVersion);
public void execute(RealizedFlow realizedFlow) {
- if (log.isTraceEnabled())
- log.trace("Executing " + realizedFlow);
-
String moduleName = realizedFlow.getModuleName();
String moduleVersion = realizedFlow.getModuleVersion();
--- /dev/null
+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.slc.cli.posix.PosixCommands;
+
+/** Argeo command line tools. */
+public class ArgeoCli extends CommandsCli {
+
+ public ArgeoCli(String commandName) {
+ super(commandName);
+ // Common options
+ options.addOption(Option.builder("v").hasArg().argName("verbose").desc("verbosity").build());
+ options.addOption(
+ Option.builder("D").hasArgs().argName("property=value").desc("use value for given property").build());
+
+ addCommandsCli(new PosixCommands("posix"));
+ addCommandsCli(new FsCommands("fs"));
+// addCommandsCli(new JcrCommands("jcr"));
+ }
+
+ @Override
+ public String getDescription() {
+ return "Argeo command line utilities";
+ }
+
+ public static void main(String[] args) {
+ mainImpl(new ArgeoCli("argeo"), args);
+ }
+
+}
import java.util.List;
import java.util.Map;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.DefaultNameVersion;
import org.argeo.slc.NameVersion;
import org.argeo.slc.SlcException;
* Reference implementation of args to URIs algorithm.
*/
public class DefaultAgentCli implements SlcAgentCli {
- private final static CmsLog log = CmsLog.getLog(DefaultAgentCli.class);
-
private final static String UTF8 = "UTF-8";
private SlcAgent agent;
// private AuthenticationManager authenticationManager;
if (args.length > 0 && args[0].equals("help")) {
StringBuilder buf = new StringBuilder();
help(args, buf);
- log.info("\n" + buf);
+// log.info("\n" + buf);
return buf.toString();
} else {
List<URI> uris = asURIs(args);
package org.argeo.slc.runtime;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.WARNING;
+
+import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.execution.ExecutionContext;
import org.argeo.slc.execution.ExecutionFlow;
/** Default implementation of an execution flow. */
public class DefaultExecutionFlow implements ExecutionFlow {
- private final static CmsLog log = CmsLog.getLog(DefaultExecutionFlow.class);
+ private final static System.Logger logger = System.getLogger(DefaultExecutionFlow.class.getName());
private final ExecutionSpec executionSpec;
private String name = null;
try {
for (Runnable executable : executables) {
if (Thread.interrupted()) {
- log.error("Flow '" + getName() + "' killed before '" + executable + "'");
+ logger.log(ERROR, "Flow '" + getName() + "' killed before '" + executable + "'");
Thread.currentThread().interrupt();
return;
// throw new ThreadDeath();
}
} catch (RuntimeException e) {
if (Thread.interrupted()) {
- log.error("Flow '" + getName() + "' killed while receiving an unrelated exception", e);
+ logger.log(ERROR, "Flow '" + getName() + "' killed while receiving an unrelated exception", e);
Thread.currentThread().interrupt();
return;
// throw new ThreadDeath();
if (failOnError)
throw e;
else {
- log.error("Execution flow failed," + " but process did not fail" + " because failOnError property"
- + " is set to false: " + e);
- if (log.isTraceEnabled())
+ logger.log(ERROR, "Execution flow failed," + " but process did not fail"
+ + " because failOnError property" + " is set to false: " + e);
+ if (logger.isLoggable(Level.TRACE))
e.printStackTrace();
}
}
DefaultExecutionFlow flow = (DefaultExecutionFlow) executable;
String newPath = path + '/' + flow.getName();
flow.setPath(newPath);
- log.warn(newPath + " was forcibly set on " + flow);
+ logger.log(WARNING, newPath + " was forcibly set on " + flow);
}
}
}
import java.util.Stack;
import java.util.UUID;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.execution.ExecutionFlow;
import org.argeo.slc.execution.ExecutionSpecAttribute;
/** Canonical implementation of an execution stack. */
public class DefaultExecutionStack implements ExecutionStack {
-
- private final static CmsLog log = CmsLog
- .getLog(DefaultExecutionStack.class);
-
private final Stack<ExecutionFlowRuntime> stack = new Stack<ExecutionFlowRuntime>();
public synchronized void enterFlow(ExecutionFlow executionFlow) {
ExecutionFlowRuntime runtime = new ExecutionFlowRuntime(executionFlow);
stack.push(runtime);
- Map<String, ExecutionSpecAttribute> specAttrs = executionFlow
- .getExecutionSpec().getAttributes();
+ Map<String, ExecutionSpecAttribute> specAttrs = executionFlow.getExecutionSpec().getAttributes();
for (String key : specAttrs.keySet()) {
if (executionFlow.isSetAsParameter(key)) {
- runtime.getLocalVariables().put(key,
- executionFlow.getParameter(key));
+ runtime.getLocalVariables().put(key, executionFlow.getParameter(key));
}
}
}
public synchronized void leaveFlow(ExecutionFlow executionFlow) {
ExecutionFlowRuntime leftEf = stack.pop();
- if (!leftEf.getExecutionFlow().getName()
- .equals(executionFlow.getName()))
- throw new SlcException("Asked to leave " + executionFlow
- + " but last is " + leftEf);
+ if (!leftEf.getExecutionFlow().getName().equals(executionFlow.getName()))
+ throw new SlcException("Asked to leave " + executionFlow + " but last is " + leftEf);
leftEf.getScopedObjects().clear();
leftEf.getLocalVariables().clear();
public synchronized void addScopedObject(String name, Object obj) {
ExecutionFlowRuntime runtime = stack.peek();
// TODO: check that the object is not set yet ?
- if (log.isDebugEnabled()) {
- Object existing = findScopedObject(name);
- if (existing != null)
- log.warn("Scoped object " + name + " of type " + obj.getClass()
- + " already registered in " + runtime);
- }
+// if (log.isDebugEnabled()) {
+// Object existing = findScopedObject(name);
+// if (existing != null)
+// log.warn("Scoped object " + name + " of type " + obj.getClass()
+// + " already registered in " + runtime);
+// }
runtime.getScopedObjects().put(name, obj);
}
package org.argeo.slc.runtime;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.WARNING;
+
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import javax.security.auth.Subject;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.execution.ExecutionFlowDescriptor;
import org.argeo.slc.execution.ExecutionModulesManager;
import org.argeo.slc.execution.ExecutionStep;
/** Thread of a single execution */
public class ExecutionThread extends Thread {
public final static String SYSPROP_EXECUTION_AUTO_UPGRADE = "slc.execution.autoupgrade";
- private final static CmsLog log = CmsLog.getLog(ExecutionThread.class);
+ private final static System.Logger logger = System.getLogger(ExecutionThread.class.getName());
private ExecutionModulesManager executionModulesManager;
private final RealizedFlow realizedFlow;
}
} catch (FlowConfigurationException e) {
String msg = "Configuration problem with flow " + flowName + ":\n" + e.getMessage();
- log.error(msg);
+ logger.log(ERROR, msg);
getProcessThreadGroup().dispatchAddStep(
new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
} catch (Exception e) {
// TODO: re-throw exception ?
String msg = "Execution of flow " + flowName + " failed.";
- log.error(msg, e);
+ logger.log(ERROR, msg, e);
getProcessThreadGroup().dispatchAddStep(
new ExecutionStep(realizedFlow.getModuleName(), ExecutionStep.ERROR, msg + " " + e.getMessage()));
} finally {
try {
destructionCallbacks.get(i).run();
} catch (Exception e) {
- log.warn("Could not process destruction callback " + i + " in thread " + getName(), e);
+ logger.log(WARNING, "Could not process destruction callback " + i + " in thread " + getName(), e);
}
}
}
/**
- * Gather object destruction callback to be called in reverse order at the
- * end of the thread
+ * Gather object destruction callback to be called in reverse order at the end
+ * of the thread
*/
public synchronized void registerDestructionCallback(String name, Runnable callback) {
destructionCallbacks.add(callback);
package org.argeo.slc.runtime;
+import java.lang.System.Logger.Level;
import java.util.Stack;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.execution.ExecutionFlow;
import org.argeo.slc.execution.ExecutionSpecAttribute;
/** Manage parameters that need to be set during the instantiation of a flow */
public class InstantiationManager {
- private final static CmsLog log = CmsLog
- .getLog(InstantiationManager.class);
+ private final static System.Logger logger = System.getLogger(InstantiationManager.class.getName());
private ThreadLocal<Stack<ExecutionFlow>> flowStack = new ThreadLocal<Stack<ExecutionFlow>>();
public Object createRef(String name) {
if ((flowStack.get() == null) || flowStack.get().empty()) {
- throw new SlcException("No flow is currently initializing."
- + " Declare ParameterRef as inner beans or prototypes.");
+ throw new SlcException(
+ "No flow is currently initializing." + " Declare ParameterRef as inner beans or prototypes.");
}
return getInitializingFlowParameter(name);
((DefaultExecutionFlow) flow).setName(flowName);
}
- if (log.isTraceEnabled())
- log.trace("Start initialization of " + flow.hashCode() + " ("
- + flow + " - " + flow.getClass() + ")");
+ logger.log(Level.TRACE,
+ () -> "Start initialization of " + flow.hashCode() + " (" + flow + " - " + flow.getClass() + ")");
// log.info("# flowInitializationStarted " + flowName);
// create a stack for this thread if there is none
}
public void flowInitializationFinished(ExecutionFlow flow, String flowName) {
- if (log.isTraceEnabled())
- log.trace("Finish initialization of " + flow.hashCode() + " ("
- + flow + " - " + flow.getClass() + ")");
+ logger.log(Level.TRACE,
+ () -> "Finish initialization of " + flow.hashCode() + " (" + flow + " - " + flow.getClass() + ")");
if (flowStack.get() != null) {
ExecutionFlow registeredFlow = flowStack.get().pop();
}
} else {
// happens for flows imported as services
- log.warn("flowInitializationFinished - Flow Stack is null");
+ logger.log(Level.WARNING, "flowInitializationFinished - Flow Stack is null");
}
}
return flowStack.get().elementAt(i);
}
}
- throw new SlcException("Key " + key + " is not set as parameter in "
- + flowStack.get().firstElement().toString() + " (stack size="
- + flowStack.get().size() + ")");
+ throw new SlcException("Key " + key + " is not set as parameter in " + flowStack.get().firstElement().toString()
+ + " (stack size=" + flowStack.get().size() + ")");
}
}
public Class<?> getInitializingFlowParameterClass(String key) {
- ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key)
- .getExecutionSpec().getAttributes().get(key);
+ ExecutionSpecAttribute attr = findInitializingFlowWithParameter(key).getExecutionSpec().getAttributes()
+ .get(key);
if (attr instanceof RefSpecAttribute)
return ((RefSpecAttribute) attr).getTargetClass();
else if (attr instanceof PrimitiveSpecAttribute) {
String type = ((PrimitiveSpecAttribute) attr).getType();
Class<?> clss = PrimitiveUtils.typeAsClass(type);
if (clss == null)
- throw new SlcException("Cannot convert type " + type
- + " to class.");
+ throw new SlcException("Cannot convert type " + type + " to class.");
return clss;
} else
return null;
package org.argeo.slc.runtime;
+import java.lang.System.Logger.Level;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import javax.security.auth.Subject;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.execution.ExecutionModulesManager;
import org.argeo.slc.execution.ExecutionProcess;
* sequential {@link ExecutionThread}s.
*/
public class ProcessThread extends Thread {
- private final static CmsLog log = CmsLog.getLog(ProcessThread.class);
+ private final static System.Logger logger = System.getLogger(ProcessThread.class.getName());
private final ExecutionModulesManager executionModulesManager;
private final ExecutionProcess process;
// throw new SlcException("Can only execute authenticated threads");
// SecurityContextHolder.getContext().setAuthentication(authentication);
- log.info("\n##\n## SLC Process #" + process.getUuid() + " STARTED\n##\n");
+ logger.log(Level.INFO, "\n##\n## SLC Process #" + process.getUuid() + " STARTED\n##\n");
// Start logging
new LoggingThread().start();
return;
} catch (Exception e) {
String msg = "Process " + getProcess().getUuid() + " failed unexpectedly.";
- log.error(msg, e);
+ logger.log(Level.ERROR, msg, e);
getProcessThreadGroup()
.dispatchAddStep(new ExecutionStep("Process", ExecutionStep.ERROR, msg + " " + e.getMessage()));
}
process.setStatus(ExecutionProcess.COMPLETED);
// executionModulesManager.dispatchUpdateStatus(process, oldStatus,
// process.getStatus());
- log.info("\n## SLC Process #" + process.getUuid() + " " + process.getStatus() + "\n");
+ logger.log(Level.INFO, "\n## SLC Process #" + process.getUuid() + " " + process.getStatus() + "\n");
}
/** Called when being killed */
try {
executionThread.interrupt();
} catch (Exception e) {
- log.error("Cannot interrupt " + executionThread);
+ logger.log(Level.ERROR, "Cannot interrupt " + executionThread);
}
}
processThreadGroup.interrupt();
import java.io.File;
import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.nio.file.Path;
import org.apache.commons.io.FileUtils;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
public class Echo implements Runnable {
- private final static CmsLog defaultLog = CmsLog.getLog(Echo.class);
+ private final static Logger defaultLogger = System.getLogger(Echo.class.getName());
private Path writeTo = null;
- private CmsLog log;
+ private Logger log;
private Object message;
public void run() {
- log().info(message);
+ log().log(Level.INFO, message);
if (writeTo != null) {
try {
File file = writeTo.toFile();
- if (log().isDebugEnabled())
- log().debug("Write to " + file);
+
+ log().log(Level.DEBUG, () -> "Write to " + file);
if (message != null)
FileUtils.writeStringToFile(file, message.toString());
} catch (IOException e) {
}
}
- private CmsLog log() {
- return log != null ? log : defaultLog;
+ private Logger log() {
+ return log != null ? log : defaultLogger;
}
public void setMessage(Object message) {
package org.argeo.slc.runtime.tasks;
+import static java.lang.System.Logger.Level.DEBUG;
+import static java.lang.System.Logger.Level.ERROR;
+import static java.lang.System.Logger.Level.INFO;
+import static java.lang.System.Logger.Level.TRACE;
+import static java.lang.System.Logger.Level.WARNING;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Writer;
+import java.lang.System.Logger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import org.apache.commons.exec.ShutdownHookProcessDestroyer;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.UnsupportedException;
import org.argeo.slc.execution.ExecutionResources;
public class SystemCall implements Runnable {
public final static String LOG_STDOUT = "System.out";
- private final CmsLog log = CmsLog.getLog(getClass());
+ private final Logger logger = System.getLogger(getClass().getName());
private String execDir;
throw new SlcException("Cannot open a stream for " + stdInFile, e2);
}
- if (log.isTraceEnabled()) {
- log.debug("os.name=" + System.getProperty("os.name"));
- log.debug("os.arch=" + System.getProperty("os.arch"));
- log.debug("os.version=" + System.getProperty("os.version"));
- }
+ logger.log(TRACE, () -> "os.name=" + System.getProperty("os.name"));
+ logger.log(TRACE, () -> "os.arch=" + System.getProperty("os.arch"));
+ logger.log(TRACE, () -> "os.version=" + System.getProperty("os.version"));
// Execution directory
File dir = new File(getExecDirToUse());
// Command line to use
final CommandLine commandLine = createCommandLine();
if (logCommand)
- log.info("Execute command:\n" + commandLine + "\n in working directory: \n" + dir + "\n");
+ logger.log(INFO, "Execute command:\n" + commandLine + "\n in working directory: \n" + dir + "\n");
// Env variables
Map<String, String> environmentVariablesToUse = null;
commandLine = new CommandLine(commandToUse.get(0).toString());
for (int i = 1; i < commandToUse.size(); i++) {
- if (log.isTraceEnabled())
- log.debug(commandToUse.get(i));
+ if (logger.isLoggable(TRACE))
+ logger.log(TRACE, commandToUse.get(i));
commandLine.addArgument(commandToUse.get(i).toString());
}
} else {
public void onProcessComplete(int exitValue) {
String msg = "System call '" + commandLine + "' properly completed.";
- if (log.isTraceEnabled())
- log.trace(msg);
+ logger.log(TRACE, () -> msg);
if (testResult != null) {
forwardPath(testResult);
testResult.addResultPart(new SimpleResultPart(TestStatus.PASSED, msg));
if (exceptionOnFailed)
throw new SlcException(msg, e);
else
- log.error(msg, e);
+ logger.log(ERROR, msg, e);
}
releaseWatchdog();
}
// }
if ("ERROR".equals(logLevel))
- log.error(line);
+ logger.log(ERROR, line);
else if ("WARN".equals(logLevel))
- log.warn(line);
+ logger.log(WARNING, line);
+ else if ("WARNING".equals(logLevel))
+ logger.log(WARNING, line);
else if ("INFO".equals(logLevel))
- log.info(line);
+ logger.log(INFO, line);
else if ("DEBUG".equals(logLevel))
- log.debug(line);
+ logger.log(DEBUG, line);
else if ("TRACE".equals(logLevel))
- log.trace(line);
+ logger.log(TRACE, line);
else if (LOG_STDOUT.equals(logLevel))
System.out.println(line);
else if ("System.err".equals(logLevel))
try {
writer.append(line).append('\n');
} catch (IOException e) {
- log.error("Cannot write to log file", e);
+ logger.log(ERROR, "Cannot write to log file", e);
}
}
file = target.toFile();
writer = new FileWriter(file, append);
} catch (IOException e) {
- log.error("Cannot get file for " + target, e);
+ logger.log(ERROR, "Cannot get file for " + target, e);
IOUtils.closeQuietly(writer);
}
return writer;
file = target.toFile();
out = new FileOutputStream(file, false);
} catch (IOException e) {
- log.error("Cannot get file for " + target, e);
+ logger.log(ERROR, "Cannot get file for " + target, e);
IOUtils.closeQuietly(out);
}
return out;
import java.util.Map;
import java.util.TreeMap;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.test.TestResult;
import org.argeo.slc.test.TestStatus;
import org.argeo.slc.test.context.ContextAware;
/** Utilities for comparing and synchronising contexts. */
public class ContextUtils {
- private final static CmsLog log = CmsLog.getLog(ContextUtils.class);
-
- public static void compareReachedExpected(ContextAware contextAware,
- TestResult testResult) {
+ public static void compareReachedExpected(ContextAware contextAware, TestResult testResult) {
for (String key : contextAware.getExpectedValues().keySet()) {
// Compare expected values with reached ones
Object expectedValue = contextAware.getExpectedValues().get(key);
- if (expectedValue.toString().equals(
- contextAware.getContextSkipFlag())) {
- if (log.isDebugEnabled())
- log.debug("Skipped check for key '" + key + "'");
+ if (expectedValue.toString().equals(contextAware.getContextSkipFlag())) {
+// if (log.isDebugEnabled())
+// log.debug("Skipped check for key '" + key + "'");
continue;
}
Object reachedValue = contextAware.getValues().get(key);
if (expectedValue.equals(contextAware.getContextAnyFlag())) {
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.PASSED, "Expected any value for key '"
- + key + "'"));
+ testResult.addResultPart(
+ new SimpleResultPart(TestStatus.PASSED, "Expected any value for key '" + key + "'"));
} else if (expectedValue.equals(reachedValue)) {
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.PASSED, "Values matched for key '" + key
- + "'"));
+ testResult.addResultPart(
+ new SimpleResultPart(TestStatus.PASSED, "Values matched for key '" + key + "'"));
} else {
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.FAILED, "Mismatch for key '" + key
- + "': expected '" + expectedValue
- + "' but reached '" + reachedValue + "'"));
+ testResult.addResultPart(new SimpleResultPart(TestStatus.FAILED, "Mismatch for key '" + key
+ + "': expected '" + expectedValue + "' but reached '" + reachedValue + "'"));
}
} else {
- testResult.addResultPart(new SimpleResultPart(
- TestStatus.FAILED, "No value reached for key '" + key
- + "'"));
+ testResult.addResultPart(
+ new SimpleResultPart(TestStatus.FAILED, "No value reached for key '" + key + "'"));
}
}
}
/**
- * Makes sure that all children and sub-children of parent share the same
- * maps for values and expected values.
+ * Makes sure that all children and sub-children of parent share the same maps
+ * for values and expected values.
*/
public static void synchronize(ParentContextAware parent) {
- Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(
- parent.getExpectedValues());
+ Map<String, Object> expectedValuesCommon = new TreeMap<String, Object>(parent.getExpectedValues());
synchronize(parent, expectedValuesCommon);
- if (log.isDebugEnabled())
- log.debug("Synchronized context " + parent);
+// if (log.isDebugEnabled())
+// log.debug("Synchronized context " + parent);
}
- private static void synchronize(ParentContextAware parent,
- Map<String, Object> expectedValuesCommon) {
+ private static void synchronize(ParentContextAware parent, Map<String, Object> expectedValuesCommon) {
for (ContextAware child : parent.getChildContexts()) {
// Values
putNotContained(parent.getValues(), child.getValues());
// Creates a new Map in order not to disturb other context using the
// same keys
- Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(
- expectedValuesCommon);
- putNotContained(expectedValuesCommonChild,
- child.getExpectedValues());
+ Map<String, Object> expectedValuesCommonChild = new TreeMap<String, Object>(expectedValuesCommon);
+ putNotContained(expectedValuesCommonChild, child.getExpectedValues());
if (child instanceof ParentContextAware) {
// Recursive sync
- synchronize((ParentContextAware) child,
- expectedValuesCommonChild);
+ synchronize((ParentContextAware) child, expectedValuesCommonChild);
}
}
}
/**
- * Put into common map the values from child map which are not already
- * defined in common map.
+ * Put into common map the values from child map which are not already defined
+ * in common map.
*/
- public static void putNotContained(Map<String, Object> commonMap,
- Map<String, Object> childMap) {
+ public static void putNotContained(Map<String, Object> commonMap, Map<String, Object> childMap) {
for (String key : childMap.keySet()) {
if (!commonMap.containsKey(key)) {
commonMap.put(key, childMap.get(key));
}
/** Overrides child map values with the values already set in common map */
- public static void overrideContained(Map<String, Object> commonMap,
- Map<String, Object> childMap) {
+ public static void overrideContained(Map<String, Object> commonMap, Map<String, Object> childMap) {
for (String key : childMap.keySet()) {
if (commonMap.containsKey(key)) {
childMap.put(key, commonMap.get(key));
import java.util.UUID;
import java.util.Vector;
-import org.argeo.api.cms.CmsLog;
import org.argeo.slc.SlcException;
import org.argeo.slc.test.TestResult;
import org.argeo.slc.test.TestResultPart;
* Basic implementation of a test result containing only a list of result parts.
*/
public class SimpleTestResult implements TestResult {
- private static CmsLog log = CmsLog.getLog(SimpleTestResult.class);
-
private String uuid;
private String currentTestRunUuid;
public void addResultPart(TestResultPart part) {
if (throwError && part.getStatus() == ERROR) {
- throw new SlcException(
- "There was an error in the underlying test: "
- + part.getExceptionMessage());
+ throw new SlcException("There was an error in the underlying test: " + part.getExceptionMessage());
}
parts.add(part);
- if (log.isDebugEnabled())
- log.debug(part);
+// if (log.isDebugEnabled())
+// log.debug(part);
}
public void close() {
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+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() {
+
+ }
+}
--- /dev/null
+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();
+ }
+
+ }
+}
Bundle-License: Apache-2.0
-SLC-Origin-M2: biz.aQute.bnd:biz.aQute.bndlib:4.2.0
+SLC-Origin-M2: biz.aQute.bnd:biz.aQute.bndlib:5.3.0
SLC-Origin-ManifestNotModified: true
Bundle-License: EPL-2.0
SLC-Origin-M2: org.eclipse.jdt:ecj:3.28.0
-SLC-Origin-ManifestNotModified: true
\ No newline at end of file
+SLC-Origin-ManifestNotModified: true
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
\ No newline at end of file