summaryrefslogtreecommitdiff
path: root/module/ri-engine/src/main
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2021-02-03 16:35:48 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2021-02-03 16:35:48 +0100
commitbafe762ac01d16904c18404283027e426e19bc73 (patch)
treec22688ad186f5ce635f525704c5035f91b983b68 /module/ri-engine/src/main
parent91abd0b04320a9c9d932df195aca38c1cacfcc5a (diff)
downloadrules-sandbox-bafe762ac01d16904c18404283027e426e19bc73.tar.gz
rules-sandbox-bafe762ac01d16904c18404283027e426e19bc73.tar.bz2
rules-sandbox-bafe762ac01d16904c18404283027e426e19bc73.tar.xz
rules-sandbox-bafe762ac01d16904c18404283027e426e19bc73.zip
Code reorganization.
Moving main code to src, keeping modules in modules/
Diffstat (limited to 'module/ri-engine/src/main')
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java365
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/DbObject.java16
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/Engine.java172
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/JinjavaTemplateEngine.java51
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java21
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateLoader.java7
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/DatabaseCommand.java20
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/EngineFile.java18
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/NinjaCommand.java156
-rw-r--r--module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/RunCommand.java82
10 files changed, 0 insertions, 908 deletions
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java
deleted file mode 100644
index 7dc24ad..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbIo.java
+++ /dev/null
@@ -1,365 +0,0 @@
-package io.trygvis.rules.engine;
-
-import ch.qos.logback.core.util.FileUtil;
-import com.fasterxml.jackson.annotation.ObjectIdGenerators;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.PropertyName;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.introspect.Annotated;
-import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
-import com.fasterxml.jackson.databind.introspect.ObjectIdInfo;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
-import org.drools.core.common.DefaultFactHandle;
-import org.drools.core.factmodel.GeneratedFact;
-import org.kie.api.KieBase;
-import org.kie.api.runtime.KieContainer;
-import org.kie.api.runtime.rule.FactHandle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.*;
-import java.util.function.Function;
-
-@SuppressWarnings("unchecked")
-public class DbIo {
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final ObjectMapper mapper;
-
- private static final List<String> prioritizedKeys = List.of("key", "name", "fqdn");
-
- public DbIo(KieContainer container, KieBase kieBase) {
- var factory = new YAMLFactory();
- factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID);
- factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID);
- mapper = new ObjectMapper(factory);
- mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
- var typeFactory = TypeFactory.defaultInstance()
- .withClassLoader(new DbClassLoader(container, kieBase));
- mapper.setTypeFactory(typeFactory);
- mapper.findAndRegisterModules();
-
- mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
- @Override
- public ObjectIdInfo findObjectIdInfo(Annotated a) {
- final Class<?> klass = a.getRawType();
- if (GeneratedFact.class.isAssignableFrom(klass)) {
- System.out.println("klass = " + klass);
-
- for (String name : prioritizedKeys) {
- try {
- final String getter = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
- klass.getMethod(getter);
- return new ObjectIdInfo(PropertyName.construct(name), null, ObjectIdGenerators.PropertyGenerator.class, null);
- } catch (NoSuchMethodException ignore) {
- }
- }
- System.out.println("a.getRawType() = " + klass);
- return new ObjectIdInfo(null, null, ObjectIdGenerators.IntSequenceGenerator.class, null);
- }
-
- return super.findObjectIdInfo(a);
- }
- });
- }
-
- public List<Object> load(File file) throws IOException {
- var parser = mapper.getFactory().createParser(file);
-
- var objects = parser.<List<DbObject>>readValueAs(new TypeReference<List<DbObject>>() {});
-
- var items = new ArrayList<>();
- for (DbObject object : objects) {
- try {
- var type = mapper.getTypeFactory().findClass(object.type);
- var x = mapper.treeToValue(object.data, type);
- if (x == null) {
- x = type.getDeclaredConstructor().newInstance();
- }
- items.add(x);
- } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
- System.out.println("e.getClass() = " + e.getClass().getName());
- System.out.println("e.getMessage() = " + e.getMessage());
- // ignore
- }
- }
-
- return items;
- }
-
- public void dump(File file, Collection<FactHandle> factHandles) throws IOException {
- dump(file, factHandles, (o) -> true);
- }
-
- // This should just sort by all getters instead.
- static class FactCollection<T> {
- public final Class<T> type;
- public final List<T> values;
-
- public FactCollection(Class<T> type) {
- this.type = type;
- this.values = new ArrayList<>();
- }
-
- public void sort() {
- var comparator = comparable(type);
-
- this.values.sort(comparator);
- }
- }
-
- private static final Map<Class<?>, Comparator> comparators = new HashMap<>();
-
- private static <A, T extends Comparable<T>> Comparator comparable(Class<A> klass) {
- var comparator = comparators.get(klass);
- if (comparator != null) {
- return comparator;
- }
-
- // TODO: check if klass is a Comparable directly.
-
- var discoveredFieldsP1 = new LinkedHashMap<String, Function<Object, Object>>();
- var discoveredFieldsP2 = new LinkedHashMap<String, Function<Object, Object>>();
-
- var prioritizedTypes = List.of(String.class, int.class, Number.class);
-
- for (var f : klass.getDeclaredFields()) {
- if (f.getDeclaringClass() == Object.class) {
- continue;
- }
-
- if (!f.trySetAccessible()) {
- continue;
- }
-
- var collection = discoveredFieldsP2;
-
- if (prioritizedTypes.contains(f.getType())) {
- collection = discoveredFieldsP1;
- }
-
- collection.put(f.getName(), (Object o) -> {
- try {
- return f.get(o);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- });
- }
-
-// for (var m : klass.getFields()) {
-// if (m.getParameterCount() != 0) {
-// continue;
-// }
-//
-// var name = m.getName();
-//
-// if (name.startsWith("get") && name.length() > 3 && Character.isUpperCase(name.charAt(4))) {
-// name = name.substring(3, 3).toLowerCase() + name.substring(4);
-// } else {
-// continue;
-// }
-//
-// if (!m.isAccessible()) {
-// if (!m.trySetAccessible())
-// return null;
-// }
-//
-// discoveredFields.put(name, m);
-// }
-
-// System.out.printf("Sorting %s by:%n", klass.getName());
-
- var discoveredFields = new LinkedHashMap<>(discoveredFieldsP1);
- discoveredFields.putAll(discoveredFieldsP2);
-
- List<Function<Object, Object>> accessors = new ArrayList<>();
- for (String prioritizedKey : prioritizedKeys) {
- var m = discoveredFields.remove(prioritizedKey);
- if (m == null) {
- continue;
- }
-
- accessors.add(m);
-// System.out.println(" + " + prioritizedKey);
- }
- accessors.addAll(discoveredFields.values());
-// discoveredFields.keySet().forEach((s)-> System.out.println(" - " + s));
-
- comparator = (a, b) -> {
-// if (klass.getName().contains("AcmeServer")) {
-// System.out.println("AcmeIo.comparable");
-// }
-
- for (var method : accessors) {
- var x = method.apply(a);
- var y = method.apply(b);
-
- if (x == null && y == null) {
- continue;
- }
-
- if (x == null) {
- return -1;
- } else if (y == null) {
- return 1;
- } else {
- var res = x.toString().compareTo(y.toString());
- if (res != 0) {
- return res;
- }
- }
- }
-
- return 0;
- };
-
- comparators.put(klass, comparator);
-
- return comparator;
- }
-
- static record DbObject2(String type, Object data) {
- }
-
- public void dump(File file, Collection<FactHandle> factHandles, Function<Object, Boolean> filter) throws IOException {
- FileUtil.createMissingParentDirectories(file);
-
- var facts = new TreeMap<Class<?>, FactCollection<Object>>(Comparator.comparing(Class::getName));
- for (var handle : factHandles) {
- if (handle instanceof DefaultFactHandle h) {
- var obj = h.getObject();
- if (!filter.apply(obj)) {
- continue;
- }
-
- Class<?> type = obj.getClass();
- var collection = facts.get(type);
-
- if (collection == null) {
- collection = new FactCollection(type);
- facts.put(type, collection);
- }
-
- collection.values.add(obj);
- }
- }
-
- var objects = new ArrayList<DbObject2>(facts.size());
- for (var e : facts.entrySet()) {
- var name = e.getKey().getName();
-
- var collection = e.getValue();
- collection.sort();
- for (var fact : collection.values) {
- objects.add(new DbObject2(name, fact));
- }
- }
-
- objects.sort(new DbObjectComparator());
-
- var factory = mapper.getFactory();
- try (var writer = new FileWriter(file);
- var g = factory.createGenerator(writer)) {
- g.writeObject(objects);
- }
- }
-
- private class DbClassLoader extends ClassLoader {
- private final KieContainer container;
- private final KieBase kieBase;
-
- public DbClassLoader(KieContainer container, KieBase kieBase) {
- this.container = container;
- this.kieBase = kieBase;
- }
-
- @Override
- public Class<?> loadClass(String name) throws ClassNotFoundException {
- logger.info("Loading class {}", name);
- try {
- var klass = super.loadClass(name);
- logger.info("Found class in super classloader");
- return klass;
- } catch (ClassNotFoundException e) {
- var i = name.lastIndexOf('.');
- String pkg, simpleName;
- if (i == -1) {
- pkg = null;
- simpleName = name;
- } else {
- pkg = name.substring(0, i);
- simpleName = name.substring(i + 1);
- }
-
- try {
- var klass = container.getClassLoader().loadClass(name);
- logger.info("Found class in container's classloader");
- return klass;
- } catch (ClassNotFoundException ignore) {
- }
-
- try {
- logger.info("pkg = {}", pkg);
- logger.info("simpleName = {}", simpleName);
- var clazz = kieBase.getFactType(pkg, simpleName);
- if (clazz != null) {
- logger.info("Found class as a FactType");
- return clazz.getFactClass();
- }
- } catch (UnsupportedOperationException ignore) {
- }
-
- logger.warn("Class not found: {}", name);
-
- throw e;
- }
- }
- }
-
- private static class DbObjectComparator implements Comparator<DbObject2> {
- private final List<String> prioritizedPackages = List.of(
- "io.trygvis.rules.machine",
- "io.trygvis.rules.network",
- "io.trygvis.rules.dns",
- "io.trygvis.rules.dba",
- "io.trygvis.rules",
- "io.trygvis.rules.core");
-
- @Override
- public int compare(DbObject2 a, DbObject2 b) {
- var indexA = a.type.lastIndexOf(".");
- String packageA = indexA == -1 ? null : a.type.substring(0, indexA);
- String classA = indexA == -1 ? a.type : a.type.substring(indexA + 1);
-
- var indexB = b.type.lastIndexOf(".");
- String packageB = indexB == -1 ? null : b.type.substring(0, indexB);
- String classB = indexB == -1 ? b.type : b.type.substring(indexB + 1);
-
- var priIdxA = prioritizedPackages.indexOf(packageA);
- var priIdxB = prioritizedPackages.indexOf(packageB);
-
- if (priIdxA == -1 && priIdxB == -1) {
- return classB.compareTo(classA);
- } else if (priIdxA == -1) {
- return 1;
- } else if (priIdxB == -1) {
- return -1;
- }
- return priIdxA - priIdxB;
-// var diff = priIdxB - priIdxA;
-// if (diff != 0) {
-// return diff;
-// }
-//
-// return classB.compareTo(classA);
- }
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbObject.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbObject.java
deleted file mode 100644
index 6b9817e..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/DbObject.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package io.trygvis.rules.engine;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-public final class DbObject {
- public String type;
- public ObjectNode data;
-
- public DbObject() {
- }
-
- public DbObject(String type, ObjectNode data) {
- this.type = type;
- this.data = data;
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/Engine.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/Engine.java
deleted file mode 100644
index f2247d3..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/Engine.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package io.trygvis.rules.engine;
-
-import org.drools.core.audit.WorkingMemoryConsoleLogger;
-import org.drools.core.base.MapGlobalResolver;
-import org.drools.reflective.classloader.ProjectClassLoader;
-import org.kie.api.KieServices;
-import org.kie.api.event.rule.AgendaEventListener;
-import org.kie.api.event.rule.RuleRuntimeEventListener;
-import org.kie.api.io.Resource;
-import org.kie.api.runtime.KieContainer;
-import org.kie.api.runtime.KieSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.Nullable;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Engine implements Closeable {
- @SuppressWarnings("FieldCanBeLocal")
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- public final String name;
- @Nullable
- public final File output;
- public final DbIo io;
- public final KieSession session;
-
- public Engine(String name, File[] databases, @Nullable File output, String[] agendaGroups, File[] modules)
- throws IOException {
- this.name = name;
- this.output = output;
-
- logger.info("Getting KieServices");
-
- var services = KieServices.Factory.get();
-
- var kieRepository = services.getRepository();
-
- KieContainer container;
- TemplateLoader templateLoader;
- if (modules != null && modules.length > 0) {
- List<Resource> resources = new ArrayList<>();
- List<URL> files = new ArrayList<>();
- for (File path : modules) {
- if (!path.exists()) {
- logger.warn("Module path does not exist: {}", path.getAbsolutePath());
- continue;
- }
-
- logger.info("New KieBuilder: {}, file={}, directory={}", path, path.isFile(), path.isDirectory());
-
- if (path.isFile()) {
- files.add(path.toURI().toURL());
- }
-
- var resource = services.getResources().newFileSystemResource(path);
- logger.info("resource.getResourceType() = {}", resource.getResourceType());
- resources.add(resource);
- }
-
- var module = kieRepository.addKieModule(resources.get(0), resources.subList(1, resources.size()).toArray(new Resource[0]));
- logger.info("module.getReleaseId() = {}", module.getReleaseId());
- var rId = module.getReleaseId();
-
- logger.info("Creating classpath container, releaseId=" + rId);
- container = services.newKieContainer(rId);
-
- templateLoader = new ClasspathTemplateLoader(new URLClassLoader(files.toArray(new URL[0])));
- } else {
- var classLoader = ProjectClassLoader.findParentClassLoader();
- container = services.getKieClasspathContainer(classLoader);
- templateLoader = new ClasspathTemplateLoader(classLoader);
- }
-
- logger.info("Creating KieBase \"{}\"", name);
- logger.info("Available kie base names: {}", container.getKieBaseNames());
- var kieBase = container.getKieBase(name);
-
- session = container.newKieSession(name);
-
- var l = new WorkingMemoryConsoleLogger(session);
- session.addEventListener((AgendaEventListener) l);
- session.addEventListener((RuleRuntimeEventListener) l);
-
- session.getGlobals().setDelegate(new EngineGlobalResolver(templateLoader));
-
- logger.info("Loading data");
- io = new DbIo(container, kieBase);
-
- List<Object> allObjects = new ArrayList<>();
- for (File database : databases) {
- var objects = io.load(database);
-
- if (objects.isEmpty()) {
- logger.warn("Did not load any objects, something is wrong");
- return;
- }
-
- logger.info("Loaded {} objects from {}", objects.size(), database);
- allObjects.addAll(objects);
- }
- logger.info("Loaded {} objects", allObjects.size());
-
- for (var object : allObjects) {
- logger.info("object = " + object);
- session.insert(object);
- }
-
- for (var agendaGroup : agendaGroups) {
- logger.info("Setting agenda: " + agendaGroup);
- session.getAgenda().getAgendaGroup(agendaGroup).setFocus();
- session.fireAllRules();
- }
- }
-
- @Override
- public void close() {
- session.dispose();
- }
-
- private static class ClasspathTemplateLoader implements TemplateLoader {
- private final ClassLoader classLoader;
-
- private ClasspathTemplateLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- @Override
- public String load(String name) throws IOException {
- var resource = "templates/" + name + ".j2";
-
- try (var inputStream = classLoader.getResourceAsStream(resource)) {
- if (inputStream == null) {
- throw new FileNotFoundException("Classpath resource: " + resource);
- }
-
- return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
- }
- }
- }
-
- private class EngineGlobalResolver extends MapGlobalResolver {
- private final TemplateLoader templateLoader;
-
- public EngineGlobalResolver() {
- templateLoader = null;
- }
-
- public EngineGlobalResolver(TemplateLoader templateLoader) {
- this.templateLoader = templateLoader;
- }
-
- @Override
- public Object resolveGlobal(String identifier) {
- if ("te".equals(identifier)) {
- if (output == null) {
- throw new IllegalArgumentException("An instance of the TemplateEngine is required, but this job is not configured with a output directory.");
- }
- return new JinjavaTemplateEngine(templateLoader, output);
- }
- return super.resolveGlobal(identifier);
- }
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/JinjavaTemplateEngine.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/JinjavaTemplateEngine.java
deleted file mode 100644
index ba23089..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/JinjavaTemplateEngine.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package io.trygvis.rules.engine;
-
-import ch.qos.logback.core.util.FileUtil;
-import com.hubspot.jinjava.Jinjava;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Map;
-import java.util.Objects;
-
-/**
- * TODO: cache templates.
- */
-public class JinjavaTemplateEngine implements TemplateEngine {
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final Jinjava jinjava = new Jinjava();
-
- private final TemplateLoader loader;
- private final File basedir;
-
- public JinjavaTemplateEngine(TemplateLoader templateLoader, File basedir) {
- Objects.requireNonNull(templateLoader);
- Objects.requireNonNull(basedir);
- this.loader = templateLoader;
- this.basedir = basedir;
- }
-
- @Override
- public void clean() {
- try {
- logger.info("Removing output directory: {}", basedir);
- FileUtils.deleteDirectory(basedir);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void template(String name, String output, Map<String, Object> params) throws IOException {
- var template = loader.load(name);
- String renderedTemplate = jinjava.render(template, params);
- var f = new File(basedir, output);
- FileUtil.createMissingParentDirectories(f);
- Files.writeString(f.toPath(), renderedTemplate);
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java
deleted file mode 100644
index dc9ed02..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/Main.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.trygvis.rules.engine;
-
-import io.trygvis.rules.engine.cli.DatabaseCommand;
-import io.trygvis.rules.engine.cli.NinjaCommand;
-import io.trygvis.rules.engine.cli.RunCommand;
-import picocli.CommandLine;
-import picocli.CommandLine.Command;
-
-@Command(
- name = "engine",
- subcommands = {RunCommand.class, DatabaseCommand.class, NinjaCommand.class},
- mixinStandardHelpOptions = true,
- version = "UNSPECIFIED")
-class Main {
-
- public static void main(String... args) {
- //noinspection InstantiationOfUtilityClass
- int exitCode = new CommandLine(new Main()).execute(args);
- System.exit(exitCode);
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateLoader.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateLoader.java
deleted file mode 100644
index 9441264..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/TemplateLoader.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.trygvis.rules.engine;
-
-import java.io.IOException;
-
-interface TemplateLoader {
- String load(String name) throws IOException;
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/DatabaseCommand.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/DatabaseCommand.java
deleted file mode 100644
index 03650b5..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/DatabaseCommand.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package io.trygvis.rules.engine.cli;
-
-import picocli.CommandLine.Command;
-
-import java.util.concurrent.Callable;
-
-import static picocli.CommandLine.Option;
-
-@Command(name = "database")
-public class DatabaseCommand implements Callable<Integer> {
-
- @Option(names = {"-v", "--verbose"})
- private boolean verbose;
-
- @Override
- public Integer call() {
- System.out.println("DatabaseCommand.call");
- return 0;
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/EngineFile.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/EngineFile.java
deleted file mode 100644
index 8da0e39..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/EngineFile.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package io.trygvis.rules.engine.cli;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class EngineFile {
- public String dbDir;
- public List<Job> jobs;
-
- public static class Job {
- public String name;
- public List<String> inputs = new ArrayList<>();
- public List<String> outputIncludes = new ArrayList<>();
- public String generatedOutput;
- public List<String> agendaGroups = new ArrayList<>();
- public List<String> modules = new ArrayList<>();
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/NinjaCommand.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/NinjaCommand.java
deleted file mode 100644
index ef5ed1d..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/NinjaCommand.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package io.trygvis.rules.engine.cli;
-
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
-import org.apache.commons.lang3.StringUtils;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.Callable;
-import java.util.stream.Collectors;
-
-import static picocli.CommandLine.Command;
-
-@Command(name = "ninja")
-public class NinjaCommand implements Callable<Integer> {
-
- public File basedir = null;
-
- public Path basepath;
-
- @Override
- public Integer call() throws Exception {
- basepath = Objects.requireNonNullElseGet(basedir, () -> new File("").getAbsoluteFile()).toPath();
-
- var factory = new YAMLFactory();
- factory.enable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID);
- factory.enable(YAMLGenerator.Feature.USE_NATIVE_OBJECT_ID);
- var mapper = new ObjectMapper(factory);
- mapper.enable(MapperFeature.AUTO_DETECT_FIELDS);
-
- var f = mapper.readValue(new File(basedir, "engine.yaml"), EngineFile.class);
-
- Path dbDir;
- if (StringUtils.trimToNull(f.dbDir) == null) {
- System.err.println("Missing required field: dbDir");
- return 1;
- } else {
- dbDir = Path.of(f.dbDir);
- }
-
- var buf = new StringWriter();
- var out = new PrintWriter(buf);
-
- out.println("# Generated");
- out.println("#");
- out.println("### engine.ninja");
- out.println("");
- out.println("rule engine-yaml-to-ninja");
- out.println(" command = engine ninja");
- out.println("");
- out.println("build engine.ninja: engine-yaml-to-ninja engine.yaml");
- out.println("");
- out.println("### engine.png");
- out.println("");
- out.println("rule ninja-to-dot");
- out.println(" command = ninja -t graph > $out");
- out.println("");
- out.println("rule dot-to-png");
- out.println(" command = dot -Tpng < $in > $out");
- out.println("");
- out.println("build engine.dot: ninja-to-dot build.ninja engine.ninja");
- out.println("");
- out.println("build engine.png: dot-to-png engine.dot");
- out.println("");
- out.println("# Jobs");
-
- for (var job : f.jobs) {
- out.println("");
-
- out.println("rule %s".formatted(job.name));
- out.println(" command=engine run $name $inputs $output_state $output_includes $generated_output $agenda_groups $modules");
- out.println();
- var dependencies = job.inputs.stream()
- .map(s -> dbDir.resolve(s + ".yaml").toString())
- .collect(Collectors.joining(" "));
-
- var outputState = dbDir.resolve(job.name + ".yaml");
-
- var generated = List.of(outputState).stream()
- .map(Path::toString)
- .collect(Collectors.joining(" "));
-
- out.println("build %s: %s %s".formatted(generated, job.name, dependencies));
- out.println(" name=--name %s".formatted(job.name));
-
- if (!job.inputs.isEmpty()) {
- var is = job.inputs.stream()
- .map(s -> "--input=" + dbDir.resolve(s + ".yaml"))
- .collect(Collectors.joining(" $\n ", "\n ", ""));
-
- out.println(" inputs=$%s".formatted(is));
- }
-
- out.println(" output_state=--output-state %s".formatted(outputState));
- if (!job.outputIncludes.isEmpty()) {
- var str = job.outputIncludes.stream()
- .map(s -> "--output-include=" + s)
- .collect(Collectors.joining(" $\n ", "\n ", ""));
-
- out.println(" output_includes=$%s".formatted(str));
- }
-
- if (job.generatedOutput != null) {
- out.println(" generated_output=--generated-output %s".formatted(fixPath(job.generatedOutput)));
- }
-
- if (!job.agendaGroups.isEmpty()) {
- var ag = job.agendaGroups.stream()
- .map(s -> "--agenda-group=" + s)
- .collect(Collectors.joining(" $\n ", "\n ", ""));
- out.println(" agenda_groups=%s".formatted(ag));
- }
-
- if (!job.modules.isEmpty()) {
- var ms = job.modules.stream()
- .map(this::fixPath)
- .map(s -> "--module=" + s)
- .collect(Collectors.joining(" $\n ", "\n ", ""));
-
- out.println(" modules=$%s".formatted(ms));
- }
- }
-
- var ninjaFile = new File(basedir, "engine.ninja");
- try (var writer = new FileWriter(ninjaFile)) {
- writer.write(buf.toString());
- }
-
- return 0;
- }
-
- private String fixPath(String s) {
- if (s.startsWith("$MODULE_HOME/")) {
- s = "$" + s;
- }
-
- var p = Path.of(s);
-
- if (p.isAbsolute()) {
- s = basepath.relativize(Path.of(s)).toString();
- }
-
- if (s.contains("*")) {
- s = "$$(echo " + s + ")";
- }
-
- return s;
- }
-}
diff --git a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/RunCommand.java b/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/RunCommand.java
deleted file mode 100644
index 35f30cd..0000000
--- a/module/ri-engine/src/main/java/io/trygvis/rules/engine/cli/RunCommand.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package io.trygvis.rules.engine.cli;
-
-import io.trygvis.rules.engine.Engine;
-
-import java.io.File;
-import java.util.concurrent.Callable;
-
-import static picocli.CommandLine.Command;
-import static picocli.CommandLine.Option;
-
-@Command(name = "run")
-public class RunCommand implements Callable<Integer> {
-
- @Option(names = {"-n", "--name"})
- public String name;
-
- @Option(names = {"-i", "--input"})
- public File[] input;
-
- @Option(names = {"--output-state"})
- public File outputState;
-
- @Option(names = {"--output-include"}, split = ",", arity = "1..*")
- public String[] outputIncludes;
-
- @Option(names = {"--generated-output"})
- public File generatedOutput;
-
- @Option(names = {"--agenda-group"})
- public String[] agendaGroups;
-
- @Option(names = {"--module"}, split = ",", arity = "1..*")
- public File[] module;
-
- @Override
- public Integer call() throws Exception {
-
- if (agendaGroups == null || agendaGroups.length == 0) {
- agendaGroups = new String[]{"init", "generate"};
- }
-
- try (var engine = new Engine(name, input, generatedOutput, agendaGroups, module)) {
- engine.io.dump(outputState, engine.session.getFactHandles(), (Object o) ->
- {
- if (outputIncludes == null || outputIncludes.length == 0) {
- return true;
- }
-
- var name = o.getClass().getName();
- var simpleName = o.getClass().getSimpleName();
-
- for (var i : outputIncludes) {
- var ok = false;
- if (i.startsWith("*")) {
- i = i.substring(1);
-
- if (i.endsWith("*")) {
- i = i.substring(1, i.length() - 2);
- ok = name.contains(i);
- } else {
- ok = name.startsWith(i) || simpleName.startsWith(i);
- }
- } else if (i.endsWith("*")) {
- i = i.substring(0, i.length() - 2);
- ok = name.startsWith(i) || simpleName.startsWith(i);
- } else {
- ok = name.equals(i) || simpleName.equals(i);
- }
-
- if (ok) {
- return true;
- }
- }
-
- return false;
- }
- );
- }
-
- return 0;
- }
-}