- * Commands can be bare Runnables or the specialized FunctionalCommand, which manages a stack of values that
- * the command execution can push. Any pushed values are matched into a global stack, and they can be referred
- * as $ (equivalent to $0) or $n (n = depth into stack) by commands that are prepared to receive them.
- * Commands that push variables into the stack should notify that to the user.
- *
- * TESTING SETUP
+ *
+ *
Commands can be bare Runnables or the specialized FunctionalCommand, which manages a stack of
+ * values that the command execution can push. Any pushed values are matched into a global stack,
+ * and they can be referred as $ (equivalent to $0) or $n (n = depth into stack) by commands that
+ * are prepared to receive them. Commands that push variables into the stack should notify that to
+ * the user.
+ *
+ *
- * Run in terminal from the project dir after "mvn install" as java -cp
+ *
+ *
Run in terminal from the project dir after "mvn install" as java -cp
* "target/kcli-0.11.0-SNAPSHOT.jar;target/lib/*" org.integratedmodelling.kcli.KlabCLI
* .
- *
- * A useful alias for bash is
*
- * alias klab="java -cp "target/kcli-0.11.0-SNAPSHOT.jar;target/lib/*"
+ *
A useful alias for bash is
+ * alias klab="java -cp "target/kcli-0.11.0-SNAPSHOT.jar;target/lib/*"
* -Xmx4096M -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
* org.integratedmodelling.kcli.KlabCLI"
- *
- * TODO revise around the {@link org.integratedmodelling.klab.api.view.modeler.Modeler} and provide
- * CLI-versions of each view instead of making up commands. Should be
- *
TODO revise around the {@link org.integratedmodelling.klab.api.view.modeler.Modeler} and
+ * provide CLI-versions of each view instead of making up commands. Should be
+ *
+ *
resources, services, statistics, report, distribution, knowledge, events, debug and context.
*/
public enum KlabCLI {
-
- INSTANCE;
-
- private String prompt = "k.LAB> ";
- private ModelerImpl modeler;
- private LineReader reader;
- private CLIStartupOptions options;
- private CommandLine commandLine;
-
- public Engine engine() {
- return modeler.engine();
+ INSTANCE;
+
+ private String prompt = "k.LAB> ";
+ private ModelerImpl modeler;
+ private LineReader reader;
+ private CLIStartupOptions options;
+ private CommandLine commandLine;
+
+ public Engine engine() {
+ return modeler.engine();
+ }
+
+ public UserScope user() {
+ return modeler.user();
+ }
+
+ public ModelerImpl modeler() {
+ return this.modeler;
+ }
+
+ private String getContextPrompt() {
+ String ret = null;
+ if (modeler.getCurrentContext() != null) {
+ ret = modeler.getCurrentSession().getName() + "/" + modeler.getCurrentContext().getName();
+ if (modeler.getCurrentContext().getContextObservation() != null) {
+ ret += "/" + modeler.getCurrentContext().getContextObservation().getName();
+ }
+ if (modeler.getCurrentContext().getObserver() != null) {
+ ret = modeler.getCurrentContext().getObserver().getName() + "@" + ret;
+ }
+ } else if (modeler.getCurrentSession() != null) {
+ ret = modeler.getCurrentSession().getName();
}
-
- public UserScope user() {
- return modeler.user();
+ return ret;
+ }
+
+ public void exportWithSchema(KlabService service, List arguments) {}
+
+ public void importWithSchema(KlabService service, String suggestedUrn, List arguments) {
+
+ ResourceTransport.Schema schema = null;
+ String result = null;
+ if (arguments == null || arguments.isEmpty()) {
+ schema = chooseSchemaInteractively(service.capabilities(user()).getImportSchemata());
+ if (schema != null) {
+ arguments = defineInteractively(service, schema);
+ arguments.addFirst("");
+ }
+ } else {
+ schema =
+ ResourceTransport.INSTANCE.findSchema(
+ arguments.getFirst(), service.capabilities(user()).getImportSchemata(), user());
}
- public ModelerImpl modeler() {
- return this.modeler;
- }
+ if (schema == null) {
+ commandLine.getErr().println("No schema found with ID " + arguments.getFirst());
+ } else if (schema.getType() == ResourceTransport.Schema.Type.STREAM && arguments.size() == 2) {
- private String getContextPrompt() {
- String ret = null;
- if (modeler.getCurrentContext() != null) {
- ret = modeler.getCurrentSession().getName() + "/" + modeler.getCurrentContext().getName();
- if (modeler.getCurrentContext().getContextObservation() != null) {
- ret += "/" + modeler.getCurrentContext().getContextObservation().getName();
- }
- if (modeler.getCurrentContext().getObserver() != null) {
- ret = modeler.getCurrentContext().getObserver().getName() + "@" + ret;
- }
- } else if (modeler.getCurrentSession() != null) {
- ret = modeler.getCurrentSession().getName();
+ if (arguments.get(1).contains("://")) {
+ try {
+ var url = new URI(arguments.get(1)).toURL();
+ result = service.importAsset(schema, schema.asset(url), suggestedUrn, user());
+ } catch (Exception e) {
+ commandLine
+ .getErr()
+ .println(
+ "Import failed with exception:"
+ + org.integratedmodelling.klab.api.utils.Utils.Exceptions.stackTrace(e));
+ return;
}
- return ret;
- }
-
- public void exportWithSchema(KlabService service, List arguments) {
-
- }
-
- public void importWithSchema(KlabService service, String suggestedUrn, List arguments) {
-
- ResourceTransport.Schema schema = null;
- String result = null;
- if (arguments == null || arguments.isEmpty()) {
- schema = chooseSchemaInteractively(service.capabilities(user()).getImportSchemata());
- if (schema != null) {
- arguments = defineInteractively(service, schema);
- arguments.addFirst("");
- }
- } else {
- schema = ResourceTransport.INSTANCE.findSchema(arguments.getFirst(),
- service.capabilities(user()).getImportSchemata(), user());
+ } else {
+ File file = new File(arguments.get(1));
+ if (file.exists()) {
+ try {
+ result = service.importAsset(schema, schema.asset(file), suggestedUrn, user());
+ } catch (Exception e) {
+ commandLine
+ .getErr()
+ .println("Import failed with exception:" + Utils.Exceptions.stackTrace(e));
+ return;
+ }
}
-
- if (schema == null) {
- commandLine.getErr().println("No schema found with ID " + arguments.getFirst());
- } else if (schema.getType() == ResourceTransport.Schema.Type.STREAM && arguments.size() == 2) {
-
- if (arguments.get(1).contains("://")) {
- try {
- var url = new URI(arguments.get(1)).toURL();
- result = service.importAsset(schema, schema.asset(url), suggestedUrn, user());
- } catch (Exception e) {
- commandLine.getErr().println("Import failed with exception:" + org.integratedmodelling.klab.api.utils.Utils.Exceptions.stackTrace(e));
- return;
- }
- } else {
- File file = new File(arguments.get(1));
- if (file.exists()) {
- try {
- result = service.importAsset(schema, schema.asset(file), suggestedUrn, user());
- } catch (Exception e) {
- commandLine.getErr().println("Import failed with exception:" + Utils.Exceptions.stackTrace(e));
- return;
- }
- }
- }
- } else {
- if (schema.getType() == ResourceTransport.Schema.Type.PROPERTIES && arguments.size() == schema.getProperties().size() + 1) {
- var params = org.integratedmodelling.klab.api.collections.Parameters.create();
- int i = 0;
- for (var property : schema.getProperties().keySet()) {
- var descriptor = schema.getProperties().get(property);
- var argValue = arguments.get(i + 1);
- if (!"_".equals(argValue)) {
- params.put(property,
- Utils.Data.convertValue(argValue,
- descriptor.type()));
- } else if (descriptor.defaultValue() != null) {
- params.put(property, descriptor.defaultValue());
- } else if (!descriptor.optional()) {
- commandLine.getErr().println("Property " + property + " is mandatory and must be " +
- "supplied");
- return;
- }
- i++;
- }
- try {
- result = service.importAsset(schema, schema.asset(params), suggestedUrn, user());
- } catch (Throwable t) {
- commandLine.getErr().println("Import failed with exception:" + Utils.Exceptions.stackTrace(t));
- return;
- }
- } else {
- commandLine.getErr().println("Import call with schema ID " + arguments.getFirst() + " " +
- "failed: argument mismatch");
- return;
- }
+ }
+ } else {
+ if (schema.getType() == ResourceTransport.Schema.Type.PROPERTIES
+ && arguments.size() == schema.getProperties().size() + 1) {
+ var params = org.integratedmodelling.klab.api.collections.Parameters.create();
+ int i = 0;
+ for (var property : schema.getProperties().keySet()) {
+ var descriptor = schema.getProperties().get(property);
+ var argValue = arguments.get(i + 1);
+ if (!"_".equals(argValue)) {
+ params.put(property, Utils.Data.convertValue(argValue, descriptor.type()));
+ } else if (descriptor.defaultValue() != null) {
+ params.put(property, descriptor.defaultValue());
+ } else if (!descriptor.optional()) {
+ commandLine
+ .getErr()
+ .println("Property " + property + " is mandatory and must be " + "supplied");
+ return;
+ }
+ i++;
}
-
- if (result == null) {
- commandLine.getErr().println("Import was rejected by service (URN is null)");
- } else {
- commandLine.getOut().println("Import to service succeeded: URN is " + result);
+ try {
+ result = service.importAsset(schema, schema.asset(params), suggestedUrn, user());
+ } catch (Throwable t) {
+ commandLine
+ .getErr()
+ .println("Import failed with exception:" + Utils.Exceptions.stackTrace(t));
+ return;
}
-
+ } else {
+ commandLine
+ .getErr()
+ .println(
+ "Import call with schema ID "
+ + arguments.getFirst()
+ + " "
+ + "failed: argument mismatch");
+ return;
+ }
}
- public ResourceTransport.Schema chooseSchemaInteractively
- (Map> schemata) {
-
- List> choices = new ArrayList<>();
- int n = 1;
- commandLine.getOut().println(Ansi.AUTO.string("Choose a transport schema:"));
- for (String key : schemata.keySet()) {
- for (var schema : schemata.get(key)) {
- commandLine.getOut().println(Ansi.AUTO.string(" " + (n++) + ": @|green " + schema.getSchemaId() + "|@ " +
- "@|yellow " + schema.getDescription() + "|@"));
- choices.add(Pair.of(key, schema));
- }
- }
- var line = reader.readLine(Ansi.AUTO.string("@|yellow Schema #:|@ "), "", (MaskingCallback) null,
+ if (result == null) {
+ commandLine.getErr().println("Import was rejected by service (URN is null)");
+ } else {
+ commandLine.getOut().println("Import to service succeeded: URN is " + result);
+ }
+ }
+
+ public ResourceTransport.Schema chooseSchemaInteractively(
+ Map> schemata) {
+
+ List> choices = new ArrayList<>();
+ int n = 1;
+ commandLine.getOut().println(Ansi.AUTO.string("Choose a transport schema:"));
+ for (String key : schemata.keySet()) {
+ for (var schema : schemata.get(key)) {
+ commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ " "
+ + (n++)
+ + ": @|green "
+ + schema.getSchemaId()
+ + "|@ "
+ + "@|yellow "
+ + schema.getDescription()
+ + "|@"));
+ choices.add(Pair.of(key, schema));
+ }
+ }
+ var line =
+ reader.readLine(
+ Ansi.AUTO.string("@|yellow Schema #:|@ "), "", (MaskingCallback) null, null);
+ if (Utils.Numbers.encodesInteger(line.trim())) {
+ var index = Integer.parseInt(line.trim()) - 1;
+ if (index >= 0 && index < choices.size()) {
+ return choices.get(index).getSecond();
+ }
+ }
+ return null;
+ }
+
+ public List defineInteractively(KlabService service, ResourceTransport.Schema schema) {
+
+ List ret = new ArrayList<>();
+
+ if (schema.getType() == ResourceTransport.Schema.Type.STREAM) {
+ var line =
+ reader.readLine(
+ Ansi.AUTO.string("@|yellow Enter file path or URL:|@ "),
+ "",
+ (MaskingCallback) null,
+ null);
+ if (line != null && !line.trim().isEmpty()) {
+ ret.add(line.trim());
+ }
+ } else if (schema.getType() == ResourceTransport.Schema.Type.PROPERTIES) {
+ for (var property : schema.getProperties().values()) {
+ var line =
+ reader.readLine(
+ Ansi.AUTO.string(
+ "Value for @|yellow "
+ + property.name()
+ + "|@ "
+ + "["
+ + (property.defaultValue() == null
+ ? (property.optional() ? "optional" : "mandatory")
+ : property.defaultValue())
+ + "]: "),
+ "",
+ (MaskingCallback) null,
null);
- if (Utils.Numbers.encodesInteger(line.trim())) {
- var index = Integer.parseInt(line.trim()) - 1;
- if (index >= 0 && index < choices.size()) {
- return choices.get(index).getSecond();
- }
+ if (line.trim().isEmpty()) {
+ ret.add("_");
+ } else {
+ ret.add(line.trim());
}
- return null;
+ }
}
-
- public List defineInteractively(KlabService service, ResourceTransport.Schema schema) {
-
- List ret = new ArrayList<>();
-
- if (schema.getType() == ResourceTransport.Schema.Type.STREAM) {
- var line = reader.readLine(Ansi.AUTO.string("@|yellow Enter file path or URL:|@ "), "",
- (MaskingCallback) null, null);
- if (line != null && !line.trim().isEmpty()) {
- ret.add(line.trim());
- }
- } else if (schema.getType() == ResourceTransport.Schema.Type.PROPERTIES) {
- for (var property : schema.getProperties().values()) {
- var line = reader.readLine(Ansi.AUTO.string("Value for @|yellow " + property.name() +
- "|@ " +
- "[" + (property.defaultValue() == null ? (property.optional() ? "optional"
- :
- "mandatory") :
- property.defaultValue()) + "]: "),
- "", (MaskingCallback) null, null);
- if (line.trim().isEmpty()) {
- ret.add("_");
- } else {
- ret.add(line.trim());
- }
- }
- }
- return ret;
+ return ret;
+ }
+
+ public T service(String service, Class serviceClass) {
+ if (service == null || "local".equals(service)) {
+ return user().getService(serviceClass);
+ } // TODO
+ return null;
+ }
+
+ public boolean confirm(String prompt) {
+ commandLine.getOut().println(Ansi.AUTO.string("@|yellow " + prompt + "|@ (Y/n)?"));
+ var line =
+ reader.readLine(Ansi.AUTO.string("@|cyan Y/n:|@ "), "", (MaskingCallback) null, null);
+ return line == null || line.isEmpty() || line.trim().equalsIgnoreCase("y");
+ }
+
+ /** Top-level command that just prints help. */
+ @Command(
+ name = "",
+ description = {
+ "k.LAB interactive shell with completion and autosuggestions. "
+ + "Hit @|magenta |@ to see available commands.",
+ "Hit" + " " + "@|magenta ALT-S|@ to toggle tailtips.",
+ ""
+ },
+ footer = {"", "Press Ctrl-D to exit."},
+ subcommands = {
+ Auth.class,
+ Expressions.class,
+ CLIReasonerView.class, /*Report.class, Resolver
+ .class,*/
+ Shutdown.class,
+ Credentials.class,
+ CLIServicesView.class,
+ Run.class,
+ PicocliCommands.ClearScreen.class,
+ CommandLine.HelpCommand.class,
+ Set.class, /*Session.class,
+ */
+ CLIObservationView.class,
+ CLIResourcesView.class,
+ Components.class,
+ Test.class,
+ Run.Alias.class,
+ Run.Unalias.class
+ })
+ static class CliCommands implements Runnable {
+
+ PrintWriter out;
+
+ public void setReader(LineReader reader) {
+ out = reader.getTerminal().writer();
}
- public T service(String service, Class serviceClass) {
- if (service == null || "local".equals(service)) {
- return user().getService(serviceClass);
- } // TODO
- return null;
+ public void run() {
+ out.println(new CommandLine(this).getUsageMessage());
}
-
- public boolean confirm(String prompt) {
- commandLine.getOut().println(Ansi.AUTO.string("@|yellow " + prompt + "|@ (Y/n)?"));
- var line = reader.readLine(Ansi.AUTO.string("@|cyan Y/n:|@ "), "", (MaskingCallback) null, null);
- return line == null || line.isEmpty() || line.trim().equalsIgnoreCase("y");
+ }
+
+ @Command(
+ name = "run",
+ mixinStandardHelpOptions = true,
+ description = {
+ "Run scripts, test cases and " + "applications.",
+ "Uses autocompletion for " + "behavior " + "and " + "test case " + "names.",
+ ""
+ },
+ subcommands = {Run.List.class, Run.Purge.class})
+ static class Run /* extends Monitor */ implements Runnable {
+
+ java.util.Set running = new LinkedHashSet<>();
+
+ static Map aliases = new LinkedHashMap<>();
+
+ @Spec CommandSpec commandSpec;
+
+ @Option(
+ names = {"-s", "--synchronous"},
+ defaultValue = "false",
+ description = {
+ "Run in synchronous"
+ + " mode,"
+ + " "
+ + "returning "
+ + "to the"
+ + " "
+ + "prompt"
+ + " "
+ + "when "
+ + "the "
+ + "script"
+ + " has"
+ + " finished "
+ + "running."
+ },
+ required = false)
+ boolean synchronous;
+
+ @Parameters(
+ description = {
+ "The full name of one or more script, test case or application.",
+ "If " + "not present locally, resolve through the k.LAB network."
+ })
+ java.util.List scriptNames = new ArrayList<>();
+
+ public Run() {}
+
+ public static void loadAliases() {
+ File aliasFile =
+ new File(
+ System.getProperty("user.home")
+ + File.separator
+ + ".klab"
+ + File.separator
+ + "kcli"
+ + File.separator
+ + "aliases.txt");
+ if (!aliasFile.exists()) {
+ // Utils.Files.touch(aliasFile);
+ }
+ try (InputStream input = new FileInputStream(aliasFile)) {
+ Properties properties = new Properties();
+ properties.load(input);
+ for (String property : properties.stringPropertyNames()) {
+ Run.aliases.put(property, properties.getProperty(property));
+ }
+ } catch (Exception e) {
+ throw new KlabIOException(e);
+ }
}
- /**
- * Top-level command that just prints help.
- */
- @Command(name = "", description = {"k.LAB interactive shell with completion and autosuggestions. " +
- "Hit @|magenta |@ to see available commands.", "Hit" +
- " " +
- "@|magenta ALT-S|@ to toggle tailtips.", ""}, footer = {"",
- "Press Ctrl-D to exit."},
- subcommands = {Auth.class, Expressions.class, CLIReasonerView.class, /*Report.class, Resolver
- .class,*/
- Shutdown.class, Credentials.class, CLIServicesView.class, Run.class,
- PicocliCommands.ClearScreen.class,
- CommandLine.HelpCommand.class, Set.class,/*Session.class,
- */CLIObservationView.class,
- CLIResourcesView.class, Components.class, Test.class, Run.Alias.class,
- Run.Unalias.class})
- static class CliCommands implements Runnable {
-
- PrintWriter out;
-
- public void setReader(LineReader reader) {
- out = reader.getTerminal().writer();
+ public static void storeAliases() {
+ File aliasFile =
+ new File(
+ System.getProperty("user.home")
+ + File.separator
+ + ".klab"
+ + File.separator
+ + "kcli"
+ + File.separator
+ + "aliases.txt");
+ try (OutputStream output = new FileOutputStream(aliasFile)) {
+ Properties properties = new Properties();
+ for (String key : Run.aliases.keySet()) {
+ properties.setProperty(key, Run.aliases.get(key));
}
+ properties.store(output, "k.CLI alias file");
+ } catch (Exception e) {
+ throw new KlabIOException(e);
+ }
+ }
- public void run() {
- out.println(new CommandLine(this).getUsageMessage());
+ @Override
+ public void run() {
+
+ PrintWriter out = commandSpec.commandLine().getOut();
+
+ if (scriptNames.isEmpty()) {
+ list();
+ } else {
+
+ for (String scriptName : scriptNames) {
+
+ // KActorsBehavior behavior = Engine.INSTANCE.getCurrentUser(true,
+ // null)
+ // .getService(ResourcesService.class)
+ // .resolveBehavior(scriptName, Engine.INSTANCE
+ // .getCurrentUser());
+ //
+ // if (behavior == null) {
+ // out.println(Ansi.AUTO.string("Behavior @|red " +
+ // scriptName +
+ // "|@ unknown or not " +
+ // "available"));
+ // } else {
+ // out.println(Ansi.AUTO.string("Running @|green " + scriptName
+ // + "|@..."));
+ // running.add(Engine.INSTANCE.getCurrentUser().run(scriptName,
+ // behavior.getType()));
+ // }
}
+ }
}
- @Command(name = "run", mixinStandardHelpOptions = true, description =
- {"Run scripts, test cases and " + "applications.", "Uses autocompletion for " + "behavior " +
- "and " +
- "test case " + "names.", ""}, subcommands = {Run.List.class, Run.Purge.class})
- static class Run /* extends Monitor */ implements Runnable {
-
- java.util.Set running = new LinkedHashSet<>();
-
- static Map aliases = new LinkedHashMap<>();
-
- @Spec
- CommandSpec commandSpec;
-
- @Option(names = {"-s", "--synchronous"}, defaultValue = "false", description = {"Run in synchronous" +
- " mode," +
- " " +
- "returning " +
- "to the" +
- " " +
- "prompt" +
- " " +
- "when " +
- "the " +
- "script" +
- " has" +
- " finished " +
- "running."}
- , required = false)
- boolean synchronous;
-
- @Parameters(description = {"The full name of one or more script, test case or application.",
- "If " +
- "not present locally, resolve through the k.LAB network."})
- java.util.List scriptNames = new ArrayList<>();
-
- public Run() {
- }
+ public void list() {
- public static void loadAliases() {
- File aliasFile =
- new File(System.getProperty("user.home") + File.separator + ".klab" + File.separator +
- "kcli" + File.separator + "aliases.txt");
- if (!aliasFile.exists()) {
- // Utils.Files.touch(aliasFile);
- }
- try (InputStream input = new FileInputStream(aliasFile)) {
- Properties properties = new Properties();
- properties.load(input);
- for (String property : properties.stringPropertyNames()) {
- Run.aliases.put(property, properties.getProperty(property));
- }
- } catch (Exception e) {
- throw new KlabIOException(e);
- }
- }
+ int n = 1;
+ for (SessionScope scope : running) {
+ commandSpec
+ .commandLine()
+ .getOut()
+ .println(" " + n++ + ". " + scope.getName() + " [" + scope.getStatus() + "]");
+ }
+ }
- public static void storeAliases() {
- File aliasFile =
- new File(System.getProperty("user.home") + File.separator + ".klab" + File.separator +
- "kcli" + File.separator + "aliases.txt");
- try (OutputStream output = new FileOutputStream(aliasFile)) {
- Properties properties = new Properties();
- for (String key : Run.aliases.keySet()) {
- properties.setProperty(key, Run.aliases.get(key));
- }
- properties.store(output, "k.CLI alias file");
- } catch (Exception e) {
- throw new KlabIOException(e);
- }
- }
+ @Command(
+ name = "list",
+ mixinStandardHelpOptions = true,
+ description = {"List all running " + "behaviors" + "."})
+ static class List implements Runnable {
- @Override
- public void run() {
+ @ParentCommand Run parent;
- PrintWriter out = commandSpec.commandLine().getOut();
-
- if (scriptNames.isEmpty()) {
- list();
- } else {
-
- for (String scriptName : scriptNames) {
-
- // KActorsBehavior behavior = Engine.INSTANCE.getCurrentUser(true,
- // null)
- // .getService(ResourcesService.class)
- // .resolveBehavior(scriptName, Engine.INSTANCE
- // .getCurrentUser());
- //
- // if (behavior == null) {
- // out.println(Ansi.AUTO.string("Behavior @|red " +
- // scriptName +
- // "|@ unknown or not " +
- // "available"));
- // } else {
- // out.println(Ansi.AUTO.string("Running @|green " + scriptName
- // + "|@..."));
- // running.add(Engine.INSTANCE.getCurrentUser().run(scriptName,
- // behavior.getType()));
- // }
- }
- }
- }
+ @Override
+ public void run() {
+ parent.list();
+ }
+ }
- public void list() {
+ @Command(
+ name = "alias",
+ mixinStandardHelpOptions = true,
+ description = {"Define an alias for a " + "command.", "Use @x to store option -x"},
+ subcommands = {Alias.List.class, Alias.Clear.class})
+ static class Alias implements Runnable {
- int n = 1;
- for (SessionScope scope : running) {
- commandSpec.commandLine().getOut().println(" " + n++ + ". " + scope.getName() + " [" + scope.getStatus() + "]");
- }
+ @Command(
+ name = "list",
+ mixinStandardHelpOptions = true,
+ description = {"List all aliases."})
+ static class List implements Runnable {
+ @Spec CommandSpec commandSpec;
+ @Override
+ public void run() {
+ for (String alias : Run.aliases.keySet()) {
+ commandSpec
+ .commandLine()
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ "@|bold " + alias + "|@: " + "@|green " + Run.aliases.get(alias) + "|@"));
+ }
}
+ }
- @Command(name = "list", mixinStandardHelpOptions = true, description = {"List all running " +
- "behaviors" +
- "."})
- static class List implements Runnable {
-
- @ParentCommand
- Run parent;
-
- @Override
- public void run() {
- parent.list();
- }
+ @Command(
+ name = "clear",
+ mixinStandardHelpOptions = true,
+ description = {"Remove all aliases."})
+ static class Clear implements Runnable {
+ @Spec CommandSpec commandSpec;
+ @Override
+ public void run() {
+ int nal = Run.aliases.size();
+ Run.aliases.clear();
+ Run.storeAliases();
+ commandSpec.commandLine().getOut().println(nal + " aliases removed");
}
-
- @Command(name = "alias", mixinStandardHelpOptions = true, description =
- {"Define an alias for a " + "command.", "Use @x to store option -x"}, subcommands =
- {Alias.List.class, Alias.Clear.class})
- static class Alias implements Runnable {
-
- @Command(name = "list", mixinStandardHelpOptions = true, description = {"List all aliases."})
- static class List implements Runnable {
- @Spec
- CommandSpec commandSpec;
-
- @Override
- public void run() {
- for (String alias : Run.aliases.keySet()) {
- commandSpec.commandLine().getOut().println(Ansi.AUTO.string("@|bold " + alias +
- "|@: " + "@|green " + Run.aliases.get(alias) + "|@"));
- }
- }
- }
-
- @Command(name = "clear", mixinStandardHelpOptions = true, description = {"Remove all aliases."})
- static class Clear implements Runnable {
- @Spec
- CommandSpec commandSpec;
-
- @Override
- public void run() {
- int nal = Run.aliases.size();
- Run.aliases.clear();
- Run.storeAliases();
- commandSpec.commandLine().getOut().println(nal + " aliases removed");
- }
- }
-
- @Parameters(defaultValue = Parameters.NULL_VALUE)
- java.util.List arguments;
- @Spec
- CommandSpec commandSpec;
-
- @Override
- public void run() {
-
- if (arguments == null || arguments.size() == 0) {
- for (String alias : Run.aliases.keySet()) {
- commandSpec.commandLine().getOut().println(Ansi.AUTO.string("@|bold " + alias +
- "|@: " + "@|green " + Run.aliases.get(alias) + "|@"));
- }
- return;
- }
-
- if (arguments.size() < 2) {
- throw new KlabIllegalStateException("Must name an alias and its value");
- }
- String alias = arguments.get(0);
- for (int i = 1; i < arguments.size(); i++) {
- if (arguments.get(i).startsWith("@")) {
- arguments.set(i, "-" + arguments.get(i).substring(1));
- }
- }
- String value = Utils.Strings.join(arguments.subList(1, arguments.size()), " ");
- Run.aliases.put(alias, value);
- Run.storeAliases();
- }
+ }
+
+ @Parameters(defaultValue = Parameters.NULL_VALUE)
+ java.util.List arguments;
+
+ @Spec CommandSpec commandSpec;
+
+ @Override
+ public void run() {
+
+ if (arguments == null || arguments.size() == 0) {
+ for (String alias : Run.aliases.keySet()) {
+ commandSpec
+ .commandLine()
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ "@|bold " + alias + "|@: " + "@|green " + Run.aliases.get(alias) + "|@"));
+ }
+ return;
}
- @Command(name = "unalias", mixinStandardHelpOptions = true, description = {"Remove a command " +
- "alias."})
- static class Unalias implements Runnable {
-
- @Parameters
- String alias;
-
- @Override
- public void run() {
- Run.aliases.remove(alias);
- Run.storeAliases();
- }
-
+ if (arguments.size() < 2) {
+ throw new KlabIllegalStateException("Must name an alias and its value");
}
-
- @Command(name = "purge", mixinStandardHelpOptions = true, description = {"Remove finished or " +
- "aborted " +
- "behaviors" +
- " from the " +
- "list."})
- static class Purge implements Runnable {
-
- @Parameters(description = {"The numeric ID of the scripts we want to purge. No argument " +
- "removes" +
- " all that have " + "finished.", "Run \"run list\" to " +
- "know " +
- "the IDs."})
- java.util.List appIds = new ArrayList<>();
-
- @ParentCommand
- Run parent;
-
- @Override
- public void run() {
- if (appIds.isEmpty()) {
- java.util.Set removed = new HashSet<>();
- for (SessionScope s : parent.running) {
- if (s.getStatus() != Status.STARTED && s.getStatus() != Status.WAITING) {
- s.close();
- removed.add(s);
- }
- }
- parent.running.removeAll(removed);
- } else {
- java.util.List scopes = new ArrayList<>(parent.running);
- for (int appId : appIds) {
- SessionScope s = scopes.get(appId + 1);
- s.close();
- parent.running.remove(s);
- }
- }
- parent.list();
- }
+ String alias = arguments.get(0);
+ for (int i = 1; i < arguments.size(); i++) {
+ if (arguments.get(i).startsWith("@")) {
+ arguments.set(i, "-" + arguments.get(i).substring(1));
+ }
}
+ String value = Utils.Strings.join(arguments.subList(1, arguments.size()), " ");
+ Run.aliases.put(alias, value);
+ Run.storeAliases();
+ }
}
- public static void main(String[] args) {
- // AnsiConsole.systemInstall();
-
- INSTANCE.options = CLIStartupOptions.create(args);
-
- try {
-
- // create the modeler
- INSTANCE.modeler = new CommandLineModeler();
- // Configure messages for CLI use
- INSTANCE.modeler.setOption(ModelerImpl.Option.UseAnsiEscapeSequences, true);
-
-
- Supplier workDir = () -> Paths.get(System.getProperty("user.home") + File.separator +
- ".klab" + File.separator + "kcli");
-
- // jline built-in commands
- workDir.get().toFile().mkdirs();
- ConfigurationPath configPath = new ConfigurationPath(workDir.get(), workDir.get());
- Builtins builtins = new Builtins(workDir, configPath, null);
- builtins.rename(Builtins.Command.TTOP, "top");
- builtins.alias("zle", "widget");
- builtins.alias("bindkey", "keymap");
-
- // picocli
- CliCommands commands = new CliCommands();
- PicocliCommandsFactory factory = new PicocliCommandsFactory();
- INSTANCE.commandLine = new CommandLine(commands, factory);
- PicocliCommands picocliCommands = new PicocliCommands(INSTANCE.commandLine);
- File historyFile = new File(Configuration.INSTANCE.getDataPath() + File.separator + "kcli" +
- ".history");
- Parser parser = new DefaultParser();
- try (Terminal terminal = TerminalBuilder.builder().build()) {
-
- SystemRegistry systemRegistry = new SystemRegistryImpl(parser, terminal, workDir, null);
- systemRegistry.setCommandRegistries(builtins, picocliCommands);
- systemRegistry.register("help", picocliCommands);
- KlabCompleter completer = new KlabCompleter(systemRegistry.completer());
- History history = new DefaultHistory();
- INSTANCE.reader =
- LineReaderBuilder.builder().terminal(terminal).completer(completer).parser(parser).variable(LineReader.LIST_MAX, 50) // candidates
- .history(history).build();
-
- builtins.setLineReader(INSTANCE.reader);
- commands.setReader(INSTANCE.reader);
- factory.setTerminal(terminal);
- history.attach(INSTANCE.reader);
-
- TailTipWidgets widgets = new TailTipWidgets(INSTANCE.reader,
- systemRegistry::commandDescription, 5,
- TailTipWidgets.TipType.COMPLETER);
- widgets.enable();
- KeyMap keyMap = INSTANCE.reader.getKeyMaps().get("main");
- keyMap.bind(new Reference("tailtip-toggle"), KeyMap.alt("s"));
-
- /**
- * If we have a command, run it and exit
- * FIXME use options field
- */
- if (args != null && args.length > 0) {
- String line = Utils.Strings.join(args, ' ');
- try {
- systemRegistry.execute(line);
- } catch (Throwable t) {
- t.printStackTrace();
- System.exit(0xff);
- }
- System.exit(0);
- }
+ @Command(
+ name = "unalias",
+ mixinStandardHelpOptions = true,
+ description = {"Remove a command " + "alias."})
+ static class Unalias implements Runnable {
- if (historyFile.exists()) {
- history.read(historyFile.toPath(), true);
- }
+ @Parameters String alias;
- Run.loadAliases();
-
- // boot the engine. This will schedule processes so it wont'delay startup.
- INSTANCE.modeler.boot();
-
- // start the shell and process input until the user quits with Ctrl-D
- String line;
- while (true) {
- try {
-
- systemRegistry.cleanUp();
- line = INSTANCE.reader.readLine(INSTANCE.prompt, INSTANCE.getContextPrompt(),
- (MaskingCallback) null, null);
- completer.resetSemanticSearch();
- boolean aliased = false;
-
- /*
- * Use <, >, .. to move through context observations, @ to set/reset the
- * observer and
- * ./? to inquire about the current context in detail. The right prompt
- * summarizes
- * the current context focus.
- */
- if (line.trim().startsWith(".") || line.trim().startsWith("<") || line.trim().startsWith("@") || line.trim().startsWith(">") || line.trim().startsWith("?")) {
- INSTANCE.setFocalScope(line.trim());
- continue;
- } else if (line.trim().startsWith("-")) {
- if (line.trim().equals("-") && history.size() > 0) {
- line = history.get(history.last() - 1);
- aliased = true;
- } else if (org.integratedmodelling.klab.api.utils.Utils.Numbers.encodesInteger(line.trim().substring(1))) {
- int n = Integer.parseInt(line.trim().substring(1));
- if (history.size() > n) {
- line = history.get(history.last() - n);
- aliased = true;
- }
- }
- } else if (Run.aliases.containsKey(line.trim())) {
- line = Run.aliases.get(line.trim());
- }
-
- if (aliased) {
- // print the actual line in grey + italic
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string("@|gray" + line +
- "|@"));
- }
-
- systemRegistry.execute(line);
-
- if (!aliased) {
- history.write(historyFile.toPath(), false);
- }
-
- } catch (UserInterruptException e) {
- // TODO send interrupt signal to running tasks
- } catch (EndOfFileException e) {
- System.exit(0);
- } catch (Exception e) {
- systemRegistry.trace(e);
- }
- }
- }
- } catch (Throwable t) {
- t.printStackTrace();
- } finally {
- // AnsiConsole.systemUninstall();
- }
+ @Override
+ public void run() {
+ Run.aliases.remove(alias);
+ Run.storeAliases();
+ }
}
-
- /**
- * Parse the string for context navigation operators and set the current context to whatever has been
- * asked for.
- *
- * @param line
- */
- private void setFocalScope(String line) {
-
- if (line.trim().equals(".")) {
-
- printContextInfo();
-
- } else if (line.trim().equals("..") || line.trim().equals("<")) {
-
- Scope scope = modeler == null ? null : (modeler.getCurrentSession() == null ? modeler.user() :
- (modeler.getCurrentContext() == null ?
- modeler.getCurrentSession() :
- modeler.getCurrentContext()));
- // context setting
- if (scope == null) {
- INSTANCE.commandLine.getOut().println("No current scope");
- } else if (scope.getType() == Scope.Type.CONTEXT) {
-
- var parent = scope.getParentScope();
- if (parent != null && parent.getType() == Scope.Type.CONTEXT) {
- modeler.setCurrentContext((ContextScope) parent);
- } else if (parent != null && parent.getType() == Scope.Type.SESSION) {
- modeler.setCurrentContext(null);
- }
- printContextInfo();
-
- } else if (scope.getType() == Scope.Type.SESSION) {
- modeler.setCurrentContext(null);
- modeler.setCurrentSession(null);
- printContextInfo();
+ @Command(
+ name = "purge",
+ mixinStandardHelpOptions = true,
+ description = {"Remove finished or " + "aborted " + "behaviors" + " from the " + "list."})
+ static class Purge implements Runnable {
+
+ @Parameters(
+ description = {
+ "The numeric ID of the scripts we want to purge. No argument "
+ + "removes"
+ + " all that have "
+ + "finished.",
+ "Run \"run list\" to " + "know " + "the IDs."
+ })
+ java.util.List appIds = new ArrayList<>();
+
+ @ParentCommand Run parent;
+
+ @Override
+ public void run() {
+ if (appIds.isEmpty()) {
+ java.util.Set removed = new HashSet<>();
+ for (SessionScope s : parent.running) {
+ if (s.getStatus() != Status.STARTED && s.getStatus() != Status.WAITING) {
+ s.close();
+ removed.add(s);
}
-
- } else if (line.startsWith("<<")) {
- this.modeler.setCurrentContext(null);
- this.modeler.setCurrentSession(null);
- } else if (line.startsWith("<")) {
- // must have something after the <
- } else if (line.startsWith(">")) {
- // show list of potential downstream observations or choose the one after the >
- } else if (line.startsWith("@")) {
- // show list of observers or choose the one after the @
+ }
+ parent.running.removeAll(removed);
+ } else {
+ java.util.List scopes = new ArrayList<>(parent.running);
+ for (int appId : appIds) {
+ SessionScope s = scopes.get(appId + 1);
+ s.close();
+ parent.running.remove(s);
+ }
}
-
- /*
- * TODO
- * < goes back one level of context observation (if any)
- * << goes back to the userscope level
- * >> goes to the innermost non-ambiguous scope and shows what's under it
- * > obsId sets the ID'd context observation as the current context or resets it if no obsId is
- * given
- * (equivalent to <)
- * @ obsId sets the observer or resets if no obsId is given
- * ? n prints out the currently known observations (at level n, 1 if not given, full tree if n ==
- * 'all')
- * ?? prints the same info as ? but much more in detail
- */
- var currentContext = user();
- if (modeler.getCurrentContext() != null) {
- currentContext = modeler.getCurrentContext();
- } else if (modeler.getCurrentSession() != null) {
- currentContext = modeler.getCurrentSession();
+ parent.list();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ // AnsiConsole.systemInstall();
+
+ INSTANCE.options = CLIStartupOptions.create(args);
+
+ try {
+
+ // create the modeler
+ INSTANCE.modeler = new CommandLineModeler();
+ // Configure messages for CLI use
+ INSTANCE.modeler.setOption(ModelerImpl.Option.UseAnsiEscapeSequences, true);
+
+ Supplier workDir =
+ () ->
+ Paths.get(
+ System.getProperty("user.home")
+ + File.separator
+ + ".klab"
+ + File.separator
+ + "kcli");
+
+ // jline built-in commands
+ workDir.get().toFile().mkdirs();
+ ConfigurationPath configPath = new ConfigurationPath(workDir.get(), workDir.get());
+ Builtins builtins = new Builtins(workDir, configPath, null);
+ builtins.rename(Builtins.Command.TTOP, "top");
+ builtins.alias("zle", "widget");
+ builtins.alias("bindkey", "keymap");
+
+ // picocli
+ CliCommands commands = new CliCommands();
+ PicocliCommandsFactory factory = new PicocliCommandsFactory();
+ INSTANCE.commandLine = new CommandLine(commands, factory);
+ PicocliCommands picocliCommands = new PicocliCommands(INSTANCE.commandLine);
+ File historyFile =
+ new File(Configuration.INSTANCE.getDataPath() + File.separator + "kcli" + ".history");
+ Parser parser = new DefaultParser();
+ try (Terminal terminal = TerminalBuilder.builder().build()) {
+
+ SystemRegistry systemRegistry = new SystemRegistryImpl(parser, terminal, workDir, null);
+ systemRegistry.setCommandRegistries(builtins, picocliCommands);
+ systemRegistry.register("help", picocliCommands);
+ KlabCompleter completer = new KlabCompleter(systemRegistry.completer());
+ History history = new DefaultHistory();
+ INSTANCE.reader =
+ LineReaderBuilder.builder()
+ .terminal(terminal)
+ .completer(completer)
+ .parser(parser)
+ .variable(LineReader.LIST_MAX, 50) // candidates
+ .history(history)
+ .build();
+
+ builtins.setLineReader(INSTANCE.reader);
+ commands.setReader(INSTANCE.reader);
+ factory.setTerminal(terminal);
+ history.attach(INSTANCE.reader);
+
+ TailTipWidgets widgets =
+ new TailTipWidgets(
+ INSTANCE.reader,
+ systemRegistry::commandDescription,
+ 5,
+ TailTipWidgets.TipType.COMPLETER);
+ widgets.enable();
+ KeyMap keyMap = INSTANCE.reader.getKeyMaps().get("main");
+ keyMap.bind(new Reference("tailtip-toggle"), KeyMap.alt("s"));
+
+ /** If we have a command, run it and exit FIXME use options field */
+ if (args != null && args.length > 0) {
+ String line = Utils.Strings.join(args, ' ');
+ try {
+ systemRegistry.execute(line);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ System.exit(0xff);
+ }
+ System.exit(0);
}
- if (currentContext == null) {
- INSTANCE.commandLine.getOut().println("No context");
- return;
+ if (historyFile.exists()) {
+ history.read(historyFile.toPath(), true);
}
- var runtime = currentContext.getService(RuntimeService.class);
- if (runtime == null) {
- INSTANCE.commandLine.getOut().println("No runtime service connected");
- return;
- }
+ Run.loadAliases();
+
+ // boot the engine. This will schedule processes so it wont'delay startup.
+ INSTANCE.modeler.boot();
+
+ // start the shell and process input until the user quits with Ctrl-D
+ String line;
+ while (true) {
+ try {
+
+ systemRegistry.cleanUp();
+ line =
+ INSTANCE.reader.readLine(
+ INSTANCE.prompt, INSTANCE.getContextPrompt(), (MaskingCallback) null, null);
+ completer.resetSemanticSearch();
+ boolean aliased = false;
+
+ /*
+ * Use <, >, .. to move through context observations, @ to set/reset the
+ * observer and
+ * ./? to inquire about the current context in detail. The right prompt
+ * summarizes
+ * the current context focus.
+ */
+ if (line.trim().startsWith(".")
+ || line.trim().startsWith("<")
+ || line.trim().startsWith("@")
+ || line.trim().startsWith(">")
+ || line.trim().startsWith("?")) {
+ INSTANCE.setFocalScope(line.trim());
+ continue;
+ } else if (line.trim().startsWith("-")) {
+ if (line.trim().equals("-") && history.size() > 0) {
+ line = history.get(history.last() - 1);
+ aliased = true;
+ } else if (org.integratedmodelling.klab.api.utils.Utils.Numbers.encodesInteger(
+ line.trim().substring(1))) {
+ int n = Integer.parseInt(line.trim().substring(1));
+ if (history.size() > n) {
+ line = history.get(history.last() - n);
+ aliased = true;
+ }
+ }
+ } else if (Run.aliases.containsKey(line.trim())) {
+ line = Run.aliases.get(line.trim());
+ }
- boolean verbose = line.startsWith("??");
- var sessionInfo = runtime.getSessionInfo(currentContext);
+ if (aliased) {
+ // print the actual line in grey + italic
+ INSTANCE.commandLine.getOut().println(Ansi.AUTO.string("@|gray" + line + "|@"));
+ }
- if (line.startsWith("?")) {
+ systemRegistry.execute(line);
- int n = 0;
- for (var session : sessionInfo) {
- listSession(session, verbose, ++n);
+ if (!aliased) {
+ history.write(historyFile.toPath(), false);
}
+ } catch (UserInterruptException e) {
+ // TODO send interrupt signal to running tasks
+ } catch (EndOfFileException e) {
+ System.exit(0);
+ } catch (Exception e) {
+ systemRegistry.trace(e);
+ }
}
-
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ } finally {
+ // AnsiConsole.systemUninstall();
}
-
- private void printContextInfo() {
- if (modeler != null && modeler.getCurrentSession() != null) {
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string("Session: @|green " + modeler.getCurrentSession().getName() + "|@"));
- if (modeler.getCurrentContext() != null) {
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string(" Context: @|green " + modeler.getCurrentContext().getName() + "|@"));
- if (modeler.getCurrentContext().getObserver() != null) {
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string(" Observer: @|green " + modeler.getCurrentContext().getObserver() + "|@"));
- }
- if (modeler.getCurrentContext().getContextObservation() != null) {
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string(" Within: @|green " + modeler.getCurrentContext().getContextObservation() + "|@"));
- }
- }
+ }
+
+ /**
+ * Parse the string for context navigation operators and set the current context to whatever has
+ * been asked for.
+ *
+ * @param line
+ */
+ private void setFocalScope(String line) {
+
+ if (line.trim().equals(".")) {
+
+ printContextInfo();
+
+ } else if (line.trim().equals("..") || line.trim().equals("<")) {
+
+ Scope scope =
+ modeler == null
+ ? null
+ : (modeler.getCurrentSession() == null
+ ? modeler.user()
+ : (modeler.getCurrentContext() == null
+ ? modeler.getCurrentSession()
+ : modeler.getCurrentContext()));
+ // context setting
+ if (scope == null) {
+ INSTANCE.commandLine.getOut().println("No current scope");
+ } else if (scope.getType() == Scope.Type.CONTEXT) {
+
+ var parent = scope.getParentScope();
+ if (parent != null && parent.getType() == Scope.Type.CONTEXT) {
+ modeler.setCurrentContext((ContextScope) parent);
+ } else if (parent != null && parent.getType() == Scope.Type.SESSION) {
+ modeler.setCurrentContext(null);
}
+ printContextInfo();
+
+ } else if (scope.getType() == Scope.Type.SESSION) {
+ modeler.setCurrentContext(null);
+ modeler.setCurrentSession(null);
+ printContextInfo();
+ }
+
+ } else if (line.startsWith("<<")) {
+ this.modeler.setCurrentContext(null);
+ this.modeler.setCurrentSession(null);
+ } else if (line.startsWith("<")) {
+ // must have something after the <
+ } else if (line.startsWith(">")) {
+ // show list of potential downstream observations or choose the one after the >
+ } else if (line.startsWith("@")) {
+ // show list of observers or choose the one after the @
}
- private void listSession(SessionInfo session, boolean verbose, int index) {
-
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string("@|green Session " + index + "|@. " + session.getName() + " [" + session.getId() + "]"));
- int n = 0;
- for (var context : session.getContexts()) {
- INSTANCE.commandLine.getOut().println(Ansi.AUTO.string(" @|yellow Context " + index + "." + (++n) + "|@. " + context.getName() + " [" + context.getId() + "]"));
- if (verbose) {
+ /*
+ * TODO
+ * < goes back one level of context observation (if any)
+ * << goes back to the userscope level
+ * >> goes to the innermost non-ambiguous scope and shows what's under it
+ * > obsId sets the ID'd context observation as the current context or resets it if no obsId is
+ * given
+ * (equivalent to <)
+ * @ obsId sets the observer or resets if no obsId is given
+ * ? n prints out the currently known observations (at level n, 1 if not given, full tree if n ==
+ * 'all')
+ * ?? prints the same info as ? but much more in detail
+ */
+ var currentContext = user();
+ if (modeler.getCurrentContext() != null) {
+ currentContext = modeler.getCurrentContext();
+ } else if (modeler.getCurrentSession() != null) {
+ currentContext = modeler.getCurrentSession();
+ }
- }
- }
+ if (currentContext == null) {
+ INSTANCE.commandLine.getOut().println("No context");
+ return;
+ }
+ var runtime = currentContext.getService(RuntimeService.class);
+ if (runtime == null) {
+ INSTANCE.commandLine.getOut().println("No runtime service connected");
+ return;
}
- // private void onEvent(Scope scope, Message message) {
- //
- // switch (message.getMessageClass()) {
- // case UserInterface -> {
- // }
- // case UserContextChange -> {
- // }
- // case UserContextDefinition -> {
- // }
- // case ServiceLifecycle -> {
- // switch (message.getMessageType()) {
- // case ServiceAvailable -> {
- // var capabilities = message.getPayload(KlabService.ServiceCapabilities
- // .class);
- // commandLine.getOut().println(Ansi.AUTO.string("@|blue " + capabilities
- // .getType() +
- // " service available: " + capabilities.getServiceName()
- // + "|@"));
- //
- // }
- // case ServiceInitializing -> {
- // var description = message.getPayload(KlabService.ServiceCapabilities.class);
- // commandLine.getOut().println(Ansi.AUTO.string("@|blue "
- // + "service initializing: " + description
- // + "|@"));
- //
- // }
- // case ServiceUnavailable -> {
- // var capabilities = message.getPayload(KlabService.ServiceCapabilities
- // .class);
- // commandLine.getOut().println(Ansi.AUTO.string("@|blue " + capabilities
- // .getType() +
- // " service unavailable: " + capabilities.getServiceName()
- // + "|@"));
- // }
- // }
- // }
- // case EngineLifecycle -> {
- // }
- // case KimLifecycle -> {
- // }
- // case ResourceLifecycle -> {
- // }
- // case ProjectLifecycle -> {
- // }
- // case Authorization -> {
- // }
- // case TaskLifecycle -> {
- // }
- // case ObservationLifecycle -> {
- // }
- // case SessionLifecycle -> {
- // }
- // case UnitTests -> {
- // }
- // case Notification -> {
- // switch (message.getMessageType()) {
- // case Info -> {
- // commandLine.getOut().println(Ansi.AUTO.string("@|blue " + message.getPayload
- // (Notification.class).getMessage()
- // + "|@"));
- // }
- // case Error -> {
- // commandLine.getOut().println(Ansi.AUTO.string("@|red " + message.getPayload
- // (Notification.class).getMessage()
- // + "|@"));
- // }
- // case Debug -> {
- // commandLine.getOut().println(Ansi.AUTO.string("@|gray " + message.getPayload
- // (Notification.class).getMessage()
- // + "|@"));
- // }
- // case Warning -> {
- // commandLine.getOut().println(Ansi.AUTO.string("@|yellow " + message
- // .getPayload(Notification.class).getMessage()
- // + "|@"));
- // }
- // default -> {
- // }
- // }
- // }
- // case Search -> {
- // }
- // case Query -> {
- // }
- // case Run -> {
- // }
- // case ViewActor -> {
- // }
- // case ActorCommunication -> {
- // }
- // default -> {
- // }
- // }
- //
- // if (message.getMessageClass() == Message.MessageClass.Notification) {
- //
- // }
- // }
-
- public static void printResourceSet(ResourceSet resourceSet, PrintStream out, int indent) {
-
- if (resourceSet == null) {
- out.println(Utils.Strings.spaces(indent) + "Null resource set");
- } else if (resourceSet.isEmpty()) {
- out.println(Utils.Strings.spaces(indent) + "Empty resource set");
- } else {
- // TODO
- out.println("Namespaces:");
- for (ResourceSet.Resource namespace : resourceSet.getNamespaces()) {
- out.println(" " + namespace);
- }
+ boolean verbose = line.startsWith("??");
+ var sessionInfo = runtime.getSessionInfo(currentContext);
+
+ if (line.startsWith("?")) {
+ int n = 0;
+ for (var session : sessionInfo) {
+ listSession(session, verbose, ++n);
+ }
+ }
+ }
+
+ private void printContextInfo() {
+ if (modeler != null && modeler.getCurrentSession() != null) {
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string("Session: @|green " + modeler.getCurrentSession().getName() + "|@"));
+ if (modeler.getCurrentContext() != null) {
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ " Context: @|green " + modeler.getCurrentContext().getName() + "|@"));
+ if (modeler.getCurrentContext().getObserver() != null) {
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ " Observer: @|green "
+ + modeler.getCurrentContext().getObserver()
+ + "|@"));
+ }
+ if (modeler.getCurrentContext().getContextObservation() != null) {
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ " Within: @|green "
+ + modeler.getCurrentContext().getContextObservation()
+ + "|@"));
}
+ }
}
-
+ }
+
+ private void listSession(SessionInfo session, boolean verbose, int index) {
+
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ "@|green Session "
+ + index
+ + "|@. "
+ + session.getName()
+ + " ["
+ + session.getId()
+ + "]"));
+ int n = 0;
+ for (var context : session.getContexts()) {
+ INSTANCE
+ .commandLine
+ .getOut()
+ .println(
+ Ansi.AUTO.string(
+ " @|yellow Context "
+ + index
+ + "."
+ + (++n)
+ + "|@. "
+ + context.getName()
+ + " ["
+ + context.getId()
+ + "]"));
+ if (verbose) {}
+ }
+ }
+
+ // private void onEvent(Scope scope, Message message) {
+ //
+ // switch (message.getMessageClass()) {
+ // case UserInterface -> {
+ // }
+ // case UserContextChange -> {
+ // }
+ // case UserContextDefinition -> {
+ // }
+ // case ServiceLifecycle -> {
+ // switch (message.getMessageType()) {
+ // case ServiceAvailable -> {
+ // var capabilities = message.getPayload(KlabService.ServiceCapabilities
+ // .class);
+ // commandLine.getOut().println(Ansi.AUTO.string("@|blue " + capabilities
+ // .getType() +
+ // " service available: " + capabilities.getServiceName()
+ // + "|@"));
+ //
+ // }
+ // case ServiceInitializing -> {
+ // var description =
+ // message.getPayload(KlabService.ServiceCapabilities.class);
+ // commandLine.getOut().println(Ansi.AUTO.string("@|blue "
+ // + "service initializing: " + description
+ // + "|@"));
+ //
+ // }
+ // case ServiceUnavailable -> {
+ // var capabilities = message.getPayload(KlabService.ServiceCapabilities
+ // .class);
+ // commandLine.getOut().println(Ansi.AUTO.string("@|blue " + capabilities
+ // .getType() +
+ // " service unavailable: " + capabilities.getServiceName()
+ // + "|@"));
+ // }
+ // }
+ // }
+ // case EngineLifecycle -> {
+ // }
+ // case KimLifecycle -> {
+ // }
+ // case ResourceLifecycle -> {
+ // }
+ // case ProjectLifecycle -> {
+ // }
+ // case Authorization -> {
+ // }
+ // case TaskLifecycle -> {
+ // }
+ // case ObservationLifecycle -> {
+ // }
+ // case SessionLifecycle -> {
+ // }
+ // case UnitTests -> {
+ // }
+ // case Notification -> {
+ // switch (message.getMessageType()) {
+ // case Info -> {
+ // commandLine.getOut().println(Ansi.AUTO.string("@|blue " +
+ // message.getPayload
+ // (Notification.class).getMessage()
+ // + "|@"));
+ // }
+ // case Error -> {
+ // commandLine.getOut().println(Ansi.AUTO.string("@|red " +
+ // message.getPayload
+ // (Notification.class).getMessage()
+ // + "|@"));
+ // }
+ // case Debug -> {
+ // commandLine.getOut().println(Ansi.AUTO.string("@|gray " +
+ // message.getPayload
+ // (Notification.class).getMessage()
+ // + "|@"));
+ // }
+ // case Warning -> {
+ // commandLine.getOut().println(Ansi.AUTO.string("@|yellow " + message
+ // .getPayload(Notification.class).getMessage()
+ // + "|@"));
+ // }
+ // default -> {
+ // }
+ // }
+ // }
+ // case Search -> {
+ // }
+ // case Query -> {
+ // }
+ // case Run -> {
+ // }
+ // case ViewActor -> {
+ // }
+ // case ActorCommunication -> {
+ // }
+ // default -> {
+ // }
+ // }
+ //
+ // if (message.getMessageClass() == Message.MessageClass.Notification) {
+ //
+ // }
+ // }
+
+ public static void printResourceSet(ResourceSet resourceSet, PrintStream out, int indent) {
+
+ if (resourceSet == null) {
+ out.println(Utils.Strings.spaces(indent) + "Null resource set");
+ } else if (resourceSet.isEmpty()) {
+ out.println(Utils.Strings.spaces(indent) + "Empty resource set");
+ } else {
+ // TODO
+ out.println("Namespaces:");
+ for (ResourceSet.Resource namespace : resourceSet.getNamespaces()) {
+ out.println(" " + namespace);
+ }
+ }
+ }
}
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIAuthenticationView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIAuthenticationView.java
index 88e1e1e5d..a70cd5b10 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIAuthenticationView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIAuthenticationView.java
@@ -4,8 +4,6 @@
import org.integratedmodelling.klab.api.view.modeler.views.AuthenticationView;
public class CLIAuthenticationView extends CLIView implements AuthenticationView {
- @Override
- public void notifyUser(UserIdentity identity) {
-
- }
+ @Override
+ public void notifyUser(UserIdentity identity) {}
}
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIDistributionView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIDistributionView.java
index d957490f0..e8c4bb374 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIDistributionView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIDistributionView.java
@@ -2,5 +2,4 @@
import org.integratedmodelling.klab.api.view.modeler.panels.DistributionView;
-public class CLIDistributionView extends CLIView implements DistributionView {
-}
+public class CLIDistributionView extends CLIView implements DistributionView {}
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIObservationView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIObservationView.java
index 9ba2a6691..20f8c9b5d 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIObservationView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIObservationView.java
@@ -1,11 +1,12 @@
package org.integratedmodelling.cli.views;
+import java.io.PrintWriter;
+import java.util.List;
import org.integratedmodelling.cli.KlabCLI;
import org.integratedmodelling.common.knowledge.KnowledgeRepository;
import org.integratedmodelling.klab.api.data.Version;
import org.integratedmodelling.klab.api.engine.Engine;
import org.integratedmodelling.klab.api.knowledge.KlabAsset;
-import org.integratedmodelling.klab.api.knowledge.Knowledge;
import org.integratedmodelling.klab.api.scope.SessionScope;
import org.integratedmodelling.klab.api.services.ResourcesService;
import org.integratedmodelling.klab.api.services.RuntimeService;
@@ -15,277 +16,306 @@
import org.integratedmodelling.klab.api.view.modeler.views.controllers.ContextViewController;
import picocli.CommandLine;
-import java.io.PrintWriter;
-import java.util.List;
-
-@CommandLine.Command(name = "observe", mixinStandardHelpOptions = true, version = Version.CURRENT,
- description = {
- "Commands to create, access and manipulate contexts.",
- ""}, subcommands = {CLIObservationView.Session.class,
- CLIObservationView.Context.class,
- CLIObservationView.Clear.class})
+@CommandLine.Command(
+ name = "observe",
+ mixinStandardHelpOptions = true,
+ version = Version.CURRENT,
+ description = {"Commands to create, access and manipulate contexts.", ""},
+ subcommands = {
+ CLIObservationView.Session.class,
+ CLIObservationView.Context.class,
+ CLIObservationView.Clear.class
+ })
public class CLIObservationView extends CLIView implements ContextView, Runnable {
- private static ContextViewController controller;
+ private static ContextViewController controller;
+
+ public CLIObservationView() {
+ controller = KlabCLI.INSTANCE.modeler().viewController(ContextViewController.class);
+ controller.registerView(this);
+ }
+
+ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec;
+
+ @CommandLine.Option(
+ names = {"-a", "--add"},
+ defaultValue = "false",
+ description = {"Add to existing context as a parallel observation"},
+ required = false)
+ boolean addToContext = false;
+
+ @CommandLine.Option(
+ names = {"-w", "--within"},
+ defaultValue = CommandLine.Parameters.NULL_VALUE,
+ description = {
+ "Choose an observation to become the context of the observation.",
+ "Use a dot to select the root subject if there is one."
+ },
+ required = false)
+ private String within;
+
+ @CommandLine.Option(
+ names = {"-g", "--geometry"},
+ defaultValue = CommandLine.Parameters.NULL_VALUE,
+ description = {
+ "Override the geometry for the new observation (must be a " + "countable/substantial)."
+ },
+ required = false)
+ private String geometry;
+
+ @CommandLine.Parameters List observables;
+
+ @Override
+ public void run() {
+
+ PrintWriter out = commandSpec.commandLine().getOut();
+ PrintWriter err = commandSpec.commandLine().getErr();
+
+ if (observables == null || observables.isEmpty()) {
+ // int n = 1;
+ // if (observationsMade.isEmpty()) {
+ // out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow No previous
+ // observations|@ "));
+ // }
+ // for (var urn : observationsMade) {
+ // out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow " + n + ".|@ " +
+ // urn));
+ // }
+ return;
+ }
- public CLIObservationView() {
- controller = KlabCLI.INSTANCE.modeler().viewController(ContextViewController.class);
- controller.registerView(this);
+ String urn = Utils.Strings.join(observables, " ");
+
+ if (Utils.Numbers.encodesInteger(urn)) {
+ int n = Integer.parseInt(urn) - 1;
+ // if (n < 0 || observationsMade.size() >= n) {
+ // err.println("No previous observation at index " + n);
+ // return;
+ // }
+ // // FIXME use SessionInfo for everything, remove any state from the controller
+ // and
+ // engine except
+ // // the current session/ctx
+ // urn = observationsMade.get(n);
+ } else {
+ // observationsMade.add(urn);
}
- @CommandLine.Spec
- CommandLine.Model.CommandSpec commandSpec;
+ var resources = KlabCLI.INSTANCE.user().getService(ResourcesService.class);
+ var resolvable = resources.resolve(urn, KlabCLI.INSTANCE.user());
+ var results =
+ KnowledgeRepository.INSTANCE.ingest(resolvable, KlabCLI.INSTANCE.user(), KlabAsset.class);
+
+ // TODO this is only for root observations
+ if (!results.isEmpty()) {
+ out.println(
+ CommandLine.Help.Ansi.AUTO.string(
+ "Observation of @|yellow "
+ + urn
+ + "|@ "
+ + "started in "
+ + results.getFirst().getUrn()));
+ KlabCLI.INSTANCE.modeler().observe(results.getFirst(), addToContext);
+ } else {
+ err.println(
+ CommandLine.Help.Ansi.AUTO.string(
+ "Can't resolve URN @|yellow " + urn + "|@ to " + "observable knowledge"));
+ }
+ }
- @CommandLine.Option(names = {"-a", "--add"}, defaultValue = "false",
- description = {"Add to existing context as a parallel observation"}, required =
- false)
- boolean addToContext = false;
+ @CommandLine.Command(
+ name = "close",
+ mixinStandardHelpOptions = true,
+ version = Version.CURRENT,
+ description = {"Close the active digital twin or session and delete all " + "observations"})
+ public static class Clear implements Runnable {
- @CommandLine.Option(names = {"-w", "--within"}, defaultValue = CommandLine.Parameters.NULL_VALUE,
- description = {
- "Choose an observation to become the context of the observation.",
- "Use a dot to select the root subject if there is one."}, required =
- false)
- private String within;
+ @CommandLine.ParentCommand CLIObservationView parent;
- @CommandLine.Option(names = {"-g", "--geometry"}, defaultValue = CommandLine.Parameters.NULL_VALUE,
- description = {
- "Override the geometry for the new observation (must be a " +
- "countable/substantial)."}, required
- = false)
- private String geometry;
+ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec;
- @CommandLine.Parameters
- List observables;
+ @CommandLine.Option(
+ names = {"-f", "--force"},
+ defaultValue = "false",
+ description = {"Close the current scope without asking for confirmation"},
+ required = false)
+ boolean force = false;
@Override
public void run() {
- PrintWriter out = commandSpec.commandLine().getOut();
- PrintWriter err = commandSpec.commandLine().getErr();
-
- if (observables == null || observables.isEmpty()) {
- // int n = 1;
- // if (observationsMade.isEmpty()) {
- // out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow No previous
- // observations|@ "));
- // }
- // for (var urn : observationsMade) {
- // out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow " + n + ".|@ " + urn));
- // }
- return;
- }
-
- String urn = Utils.Strings.join(observables, " ");
-
- if (Utils.Numbers.encodesInteger(urn)) {
- int n = Integer.parseInt(urn) - 1;
- // if (n < 0 || observationsMade.size() >= n) {
- // err.println("No previous observation at index " + n);
- // return;
- // }
- // // FIXME use SessionInfo for everything, remove any state from the controller and
- // engine except
- // // the current session/ctx
- // urn = observationsMade.get(n);
- } else {
- // observationsMade.add(urn);
- }
-
- var resources = KlabCLI.INSTANCE.user().getService(ResourcesService.class);
- var resolvable = resources.resolve(urn, KlabCLI.INSTANCE.user());
- var results = KnowledgeRepository.INSTANCE.ingest(resolvable, KlabCLI.INSTANCE.user(),
- KlabAsset.class);
-
- // TODO this is only for root observations
- if (!results.isEmpty()) {
- out.println(CommandLine.Help.Ansi.AUTO.string("Observation of @|yellow " + urn + "|@ " +
- "started in "
- + results.getFirst().getUrn()));
- KlabCLI.INSTANCE.modeler().observe(results.getFirst(), addToContext);
- } else {
- err.println(CommandLine.Help.Ansi.AUTO.string("Can't resolve URN @|yellow " + urn + "|@ to " +
- "observable knowledge"));
+ PrintWriter out = commandSpec.commandLine().getOut();
+ PrintWriter err = commandSpec.commandLine().getErr();
+
+ boolean isSession = false;
+ Channel context = KlabCLI.INSTANCE.modeler().getCurrentContext();
+ if (context == null) {
+ context = KlabCLI.INSTANCE.modeler().getCurrentSession();
+ isSession = true;
+ }
+
+ if (context == null) {
+ err.println("No current context or session.");
+ return;
+ }
+
+ if (force
+ || KlabCLI.INSTANCE.confirm(
+ "Delete the current "
+ + (isSession ? "session" : "context")
+ + " and ALL "
+ + (isSession ? "contexts and observations in them" : "observations in it"))) {
+
+ context.close();
+
+ out.println(
+ (isSession ? "Session" : "Context")
+ + " has been permanently closed and all "
+ + "data have been deleted");
+
+ KlabCLI.INSTANCE.modeler().setCurrentContext(null);
+ if (isSession) {
+ KlabCLI.INSTANCE.modeler().setCurrentSession(null);
}
+ }
}
+ }
- @CommandLine.Command(name = "close", mixinStandardHelpOptions = true, version = Version.CURRENT,
- description = {"Close the active digital twin or session and delete all " +
- "observations"})
- public static class Clear implements Runnable {
-
- @CommandLine.ParentCommand
- CLIObservationView parent;
+ /* ---- subcommands ---- */
- @CommandLine.Spec
- CommandLine.Model.CommandSpec commandSpec;
+ @CommandLine.Command(
+ name = "session",
+ mixinStandardHelpOptions = true,
+ version = Version.CURRENT,
+ description = {
+ "List the active sessions and optionally choose one by number or " + "name",
+ ""
+ },
+ subcommands = {Session.New.class})
+ public static class Session implements Runnable {
- @CommandLine.Option(names = {"-f", "--force"}, defaultValue = "false",
- description = {"Close the current scope without asking for confirmation"},
- required =
- false)
- boolean force = false;
+ @CommandLine.ParentCommand CLIObservationView parent;
- @Override
- public void run() {
+ @CommandLine.Parameters(defaultValue = "__NULL__")
+ String sessionNumberOrId;
- PrintWriter out = commandSpec.commandLine().getOut();
- PrintWriter err = commandSpec.commandLine().getErr();
+ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec;
- boolean isSession = false;
- Channel context = KlabCLI.INSTANCE.modeler().getCurrentContext();
- if (context == null) {
- context = KlabCLI.INSTANCE.modeler().getCurrentSession();
- isSession = true;
- }
-
- if (context == null) {
- err.println("No current context or session.");
- return;
- }
+ @CommandLine.Option(names = "-v", description = "print session information when listing")
+ boolean verbose;
- if (force || KlabCLI.INSTANCE.confirm("Delete the current "
- + (isSession ? "session" : "context") + " and ALL "
- + (isSession ? "contexts and observations in them" : "observations in it"))) {
-
- context.close();
-
- out.println((isSession ? "Session" : "Context") + " has been permanently closed and all " +
- "data have been deleted");
-
- KlabCLI.INSTANCE.modeler().setCurrentContext(null);
- if (isSession) {
- KlabCLI.INSTANCE.modeler().setCurrentSession(null);
- }
- }
- }
+ private static String displaySession(SessionScope session) {
+ // TODO improve and react to verbose flag
+ return "<" + session.getName() + ", id=" + session.getId() + ">";
}
- /* ---- subcommands ---- */
-
- @CommandLine.Command(name = "session", mixinStandardHelpOptions = true, version = Version.CURRENT,
- description = {"List the active sessions and optionally choose one by number or " +
- "name", ""}, subcommands = {Session.New.class})
- public static class Session implements Runnable {
-
- @CommandLine.ParentCommand
- CLIObservationView parent;
+ @Override
+ public void run() {
- @CommandLine.Parameters(defaultValue = "__NULL__")
- String sessionNumberOrId;
+ PrintWriter out = commandSpec.commandLine().getOut();
+ PrintWriter err = commandSpec.commandLine().getErr();
- @CommandLine.Spec
- CommandLine.Model.CommandSpec commandSpec;
+ if ("__NULL__".equals(sessionNumberOrId)) {
- @CommandLine.Option(names = "-v", description = "print session information when listing")
- boolean verbose;
+ var runtime = KlabCLI.INSTANCE.user().getService(RuntimeService.class);
- private static String displaySession(SessionScope session) {
- // TODO improve and react to verbose flag
- return "<" + session.getName() + ", id=" + session.getId() + ">";
+ for (var session : runtime.getSessionInfo(KlabCLI.INSTANCE.user())) {
+ // TODO this is the proper way
}
- @Override
- public void run() {
-
- PrintWriter out = commandSpec.commandLine().getOut();
- PrintWriter err = commandSpec.commandLine().getErr();
-
- if ("__NULL__".equals(sessionNumberOrId)) {
-
- var runtime = KlabCLI.INSTANCE.user().getService(RuntimeService.class);
-
- for (var session : runtime.getSessionInfo(KlabCLI.INSTANCE.user())) {
- // TODO this is the proper way
- }
-
- // FIXME below is the wrong way. Engine should only have a current session, the selected
- // runtime knows the rest.
- int n = 1;
- if (KlabCLI.INSTANCE.modeler().getOpenSessions().isEmpty()) {
- out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow No sessions|@ "));
- }
- for (var session : KlabCLI.INSTANCE.modeler().getOpenSessions()) {
- out.println(CommandLine.Help.Ansi.AUTO.string("@|green " + n + ". " + displaySession(session) + "|@"));
- }
- return;
-
- } else {
-
- SessionScope selected = null;
-
- if (Utils.Numbers.encodesInteger(sessionNumberOrId)) {
- int n = Integer.parseInt(sessionNumberOrId) - 1;
- if (n > 0 && KlabCLI.INSTANCE.modeler().getOpenSessions().size() < n) {
- selected = KlabCLI.INSTANCE.modeler().getOpenSessions().get(n);
- }
- } else for (var session : KlabCLI.INSTANCE.modeler().getOpenSessions()) {
- if (sessionNumberOrId.equals(session.getName()) || sessionNumberOrId.equals(session.getId())) {
- selected = session;
- break;
- }
- }
-
- // select the session with the passed number or name/ID
- if (selected != null) {
- KlabCLI.INSTANCE.modeler().setCurrentSession(selected);
- out.println(CommandLine.Help.Ansi.AUTO.string("@|green Session " + displaySession(selected) + "selected|@ "));
- }
+ // FIXME below is the wrong way. Engine should only have a current session, the selected
+ // runtime knows the rest.
+ int n = 1;
+ if (KlabCLI.INSTANCE.modeler().getOpenSessions().isEmpty()) {
+ out.println(CommandLine.Help.Ansi.AUTO.string("@|yellow No sessions|@ "));
+ }
+ for (var session : KlabCLI.INSTANCE.modeler().getOpenSessions()) {
+ out.println(
+ CommandLine.Help.Ansi.AUTO.string(
+ "@|green " + n + ". " + displaySession(session) + "|@"));
+ }
+ return;
+
+ } else {
+
+ SessionScope selected = null;
+
+ if (Utils.Numbers.encodesInteger(sessionNumberOrId)) {
+ int n = Integer.parseInt(sessionNumberOrId) - 1;
+ if (n > 0 && KlabCLI.INSTANCE.modeler().getOpenSessions().size() < n) {
+ selected = KlabCLI.INSTANCE.modeler().getOpenSessions().get(n);
+ }
+ } else
+ for (var session : KlabCLI.INSTANCE.modeler().getOpenSessions()) {
+ if (sessionNumberOrId.equals(session.getName())
+ || sessionNumberOrId.equals(session.getId())) {
+ selected = session;
+ break;
}
+ }
+
+ // select the session with the passed number or name/ID
+ if (selected != null) {
+ KlabCLI.INSTANCE.modeler().setCurrentSession(selected);
+ out.println(
+ CommandLine.Help.Ansi.AUTO.string(
+ "@|green Session " + displaySession(selected) + "selected|@ "));
}
+ }
+ }
- @CommandLine.Command(name = "new", mixinStandardHelpOptions = true, version = Version.CURRENT,
- description = {"Create a new session and make it current.", ""}, subcommands =
- {})
- public static class New implements Runnable {
-
- @CommandLine.ParentCommand
- Session parent;
+ @CommandLine.Command(
+ name = "new",
+ mixinStandardHelpOptions = true,
+ version = Version.CURRENT,
+ description = {"Create a new session and make it current.", ""},
+ subcommands = {})
+ public static class New implements Runnable {
- @CommandLine.Parameters(defaultValue = "__NULL__")
- String sessionName;
+ @CommandLine.ParentCommand Session parent;
- @CommandLine.Spec
- CommandLine.Model.CommandSpec commandSpec;
+ @CommandLine.Parameters(defaultValue = "__NULL__")
+ String sessionName;
- @Override
- public void run() {
+ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec;
- PrintWriter out = commandSpec.commandLine().getOut();
- PrintWriter err = commandSpec.commandLine().getErr();
+ @Override
+ public void run() {
- String sessionName = "__NULL__".equals(this.sessionName) ?
- ("Session " + (KlabCLI.INSTANCE.modeler().getOpenSessions().size() + 1)) : this.sessionName;
- var ret = KlabCLI.INSTANCE.modeler().openNewSession(sessionName);
- out.println(CommandLine.Help.Ansi.AUTO.string("@|green New session " + displaySession(ret)) +
- " created|@");
+ PrintWriter out = commandSpec.commandLine().getOut();
+ PrintWriter err = commandSpec.commandLine().getErr();
- }
- }
+ String sessionName =
+ "__NULL__".equals(this.sessionName)
+ ? ("Session " + (KlabCLI.INSTANCE.modeler().getOpenSessions().size() + 1))
+ : this.sessionName;
+ var ret = KlabCLI.INSTANCE.modeler().openNewSession(sessionName);
+ out.println(
+ CommandLine.Help.Ansi.AUTO.string("@|green New session " + displaySession(ret))
+ + " created|@");
+ }
}
+ }
+ @CommandLine.Command(
+ name = "context",
+ mixinStandardHelpOptions = true,
+ version = Version.CURRENT,
+ description = {"Connect to an existing context.", ""},
+ subcommands = {})
+ public static class Context implements Runnable {
- @CommandLine.Command(name = "context", mixinStandardHelpOptions = true, version = Version.CURRENT,
- description = {"Connect to an existing context.", ""}, subcommands = {})
- public static class Context implements Runnable {
-
- @CommandLine.ParentCommand
- CLIObservationView parent;
-
- @Override
- public void run() {
- var runtime = KlabCLI.INSTANCE.user().getService(RuntimeService.class);
- for (var session : runtime.getSessionInfo(KlabCLI.INSTANCE.user())) {
-
- }
- }
+ @CommandLine.ParentCommand CLIObservationView parent;
+ @Override
+ public void run() {
+ var runtime = KlabCLI.INSTANCE.user().getService(RuntimeService.class);
+ for (var session : runtime.getSessionInfo(KlabCLI.INSTANCE.user())) {}
}
+ }
- /* ---- view methods ---- */
+ /* ---- view methods ---- */
- @Override
- public void engineStatusChanged(Engine.Status status) {
-
- }
+ @Override
+ public void engineStatusChanged(Engine.Status status) {}
}
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIReasonerView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIReasonerView.java
index 593cfc68f..8428a6fd2 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIReasonerView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIReasonerView.java
@@ -4,6 +4,8 @@
import org.integratedmodelling.common.utils.Utils;
import org.integratedmodelling.klab.api.configuration.Configuration;
import org.integratedmodelling.klab.api.data.Version;
+import org.integratedmodelling.klab.api.digitaltwin.DigitalTwin;
+import org.integratedmodelling.klab.api.geometry.Geometry;
import org.integratedmodelling.klab.api.knowledge.Concept;
import org.integratedmodelling.klab.api.knowledge.DescriptionType;
import org.integratedmodelling.klab.api.knowledge.SemanticType;
@@ -152,6 +154,8 @@ public void run() {
var reasoner = ctx.getService(org.integratedmodelling.klab.api.services.Reasoner.class);
var observable = reasoner.resolveObservable(urn);
+ var geom = geometry == null ? null : Geometry.create(geometry);
+
if (observable == null) {
err.println(
CommandLine.Help.Ansi.AUTO.string(
@@ -169,6 +173,10 @@ public void run() {
observable = observable.builder(ctx).as(DescriptionType.ACKNOWLEDGEMENT).build();
}
+ var observation =
+ DigitalTwin.createObservation(
+ KlabCLI.INSTANCE.modeler().getCurrentScope(), observable, geometry);
+
out.println(
CommandLine.Help.Ansi.AUTO.string(
"Observation strategies for @|bold "
@@ -176,11 +184,12 @@ public void run() {
+ "|@ of @|green "
+ observable.getUrn()
+ "|@:"));
- // for (var strategy : reasoner.inferStrategies(observable, ctx)) {
- // out.println(Utils.Strings.indent(strategy.toString(),
- // Utils.Strings.fillUpLeftAligned(strategy.getCost() + ".",
- // " ", 4)));
- // }
+ for (var strategy : reasoner.computeObservationStrategies(observation, ctx)) {
+ out.println(
+ Utils.Strings.indent(
+ strategy.toString(),
+ Utils.Strings.fillUpLeftAligned(strategy.getRank() + ".", " ", 4)));
+ }
}
}
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIResourcesView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIResourcesView.java
index d7d5f7d68..00df2ba9f 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIResourcesView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIResourcesView.java
@@ -1,10 +1,10 @@
package org.integratedmodelling.cli.views;
+import java.io.PrintStream;
+import java.io.PrintWriter;
import org.integratedmodelling.cli.KlabCLI;
-import org.integratedmodelling.common.utils.Utils;
import org.integratedmodelling.klab.api.data.Version;
import org.integratedmodelling.klab.api.engine.Engine;
-import org.integratedmodelling.klab.api.exceptions.KlabIllegalStateException;
import org.integratedmodelling.klab.api.services.ResourcesService;
import org.integratedmodelling.klab.api.view.modeler.navigation.NavigableAsset;
import org.integratedmodelling.klab.api.view.modeler.navigation.NavigableContainer;
@@ -12,10 +12,6 @@
import org.integratedmodelling.klab.api.view.modeler.views.controllers.ResourcesNavigatorController;
import picocli.CommandLine;
-import java.io.File;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
@CommandLine.Command(
name = "resources",
mixinStandardHelpOptions = true,
diff --git a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIServicesView.java b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIServicesView.java
index 4d740c5c2..4832a5cd4 100644
--- a/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIServicesView.java
+++ b/klab.cli/src/main/java/org/integratedmodelling/cli/views/CLIServicesView.java
@@ -1,327 +1,377 @@
package org.integratedmodelling.cli.views;
-import org.checkerframework.checker.units.qual.K;
+import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicReference;
import org.integratedmodelling.cli.KlabCLI;
import org.integratedmodelling.common.services.client.ServiceClient;
import org.integratedmodelling.common.utils.Utils;
import org.integratedmodelling.klab.api.ServicesAPI;
import org.integratedmodelling.klab.api.engine.Engine;
-import org.integratedmodelling.klab.api.engine.distribution.RunningInstance;
import org.integratedmodelling.klab.api.services.KlabService;
-import org.integratedmodelling.klab.api.services.Reasoner;
import org.integratedmodelling.klab.api.view.modeler.views.ServicesView;
import org.integratedmodelling.klab.api.view.modeler.views.controllers.ServicesViewController;
import picocli.CommandLine;
-import java.io.PrintWriter;
-import java.util.concurrent.atomic.AtomicReference;
-
-@CommandLine.Command(name = "services",
- mixinStandardHelpOptions = true,
- description = {"List, select and control services.", "Services can be started locally " +
- "or connected from the k"
- + ".LAB network.", "Service discovery is supported according to credentials.",
- ""},
- subcommands = {org.integratedmodelling.cli.views.CLIServicesView.Connect.class,
- CLIServicesView.Resources.class, CLIServicesView.Runtime.class})
+@CommandLine.Command(
+ name = "services",
+ mixinStandardHelpOptions = true,
+ description = {
+ "List, select and control services.",
+ "Services can be started locally " + "or connected from the k" + ".LAB network.",
+ "Service discovery is supported according to credentials.",
+ ""
+ },
+ subcommands = {
+ org.integratedmodelling.cli.views.CLIServicesView.Connect.class,
+ CLIServicesView.Resources.class,
+ CLIServicesView.Runtime.class
+ })
public class CLIServicesView extends CLIView implements Runnable, ServicesView {
- private static ServicesViewController controller;
- private static AtomicReference status = new AtomicReference<>();
-
- public CLIServicesView() {
- controller = KlabCLI.INSTANCE.modeler().viewController(ServicesViewController.class);
- controller.registerView(this);
- }
-
- @CommandLine.Spec
- CommandLine.Model.CommandSpec commandSpec;
-
- @CommandLine.Option(names = {"-v", "--verbose"},
- defaultValue = "false",
- description = {"Display status and capabilities from services"},
- required = false)
- boolean verbose = false;
-
- @CommandLine.Option(names = {"-rs", "--reasoners"},
- defaultValue = "false",
- description = {"List all reasoner services."},
- required = false)
- boolean reasoners = false;
-
- @CommandLine.Option(names = {"-rv", "--resolvers"},
- defaultValue = "false",
- description = {"List all resolver services."},
- required = false)
- boolean resolvers = false;
-
- @CommandLine.Option(names = {"-rn", "--runtimes"},
- defaultValue = "false",
- description = {"List all runtime services."},
- required = false)
- boolean runtimes = false;
-
- @CommandLine.Option(names = {"-rr", "--resources"},
- defaultValue = "false",
- description = {"List all resource services."},
- required = false)
- boolean resources = false;
-
- @CommandLine.Option(names = {"-c", "--community"},
- defaultValue = "false",
- description = {"List all community services."},
- required = false)
- boolean community = false;
-
- @Override
- public void run() {
-
- PrintWriter out = commandSpec.commandLine().getOut();
-
- /*
- * TODO Print generic info about the service scope and the discovery strategy
- * installed.
- */
-
- for (var serviceType : new KlabService.Type[]{KlabService.Type.REASONER, KlabService.Type.RESOURCES
- , KlabService.Type.RESOLVER, KlabService.Type.RUNTIME, KlabService.Type.COMMUNITY,
- KlabService.Type.ENGINE}) {
-
- if (serviceType == KlabService.Type.ENGINE) {
- // TODO describe the engine
- } else {
-
- boolean first = true;
- for (var service : KlabCLI.INSTANCE.engine().serviceScope().getServices(
- serviceType.classify())) {
-
- if (reasoners && serviceType != KlabService.Type.REASONER || resolvers && serviceType != KlabService.Type.RESOLVER || resources && serviceType != KlabService.Type.RESOURCES || runtimes && serviceType != KlabService.Type.RUNTIME || community && serviceType != KlabService.Type.COMMUNITY) {
- continue;
- }
-
- /*
- * TODO tag each service with a keyword or parameter so that it can be easily
- * referenced using connect. Keep the services dictionary in the superclass.
- */
-
- if (first) {
- // out.println(serviceType);
- // TODO number for selection; highlight the name of the "current" service in
- // each category
- out.println(" " + Utils.Paths.getLast(
- service.getClass().getName(),
- '.') + ": " + service.getServiceName() + " " + " [" + (service.status().isAvailable() ? "available" : "not available") + (service instanceof ServiceClient client && client.isLocal() ? "," + "local" : "") + "] " + service.getUrl() + ServicesAPI.CAPABILITIES);
- if (verbose) {
- out.println(Utils.Strings.indent(Utils.Json.printAsJson(
- service.capabilities(KlabCLI.INSTANCE.engine().getUsers().get(0))), 6));
- }
- }
- first = false;
- }
+ private static ServicesViewController controller;
+ private static AtomicReference status = new AtomicReference<>();
+
+ public CLIServicesView() {
+ controller = KlabCLI.INSTANCE.modeler().viewController(ServicesViewController.class);
+ controller.registerView(this);
+ }
+
+ @CommandLine.Spec CommandLine.Model.CommandSpec commandSpec;
+
+ @CommandLine.Option(
+ names = {"-v", "--verbose"},
+ defaultValue = "false",
+ description = {"Display status and capabilities from services"},
+ required = false)
+ boolean verbose = false;
+
+ @CommandLine.Option(
+ names = {"-rs", "--reasoners"},
+ defaultValue = "false",
+ description = {"List all reasoner services."},
+ required = false)
+ boolean reasoners = false;
+
+ @CommandLine.Option(
+ names = {"-rv", "--resolvers"},
+ defaultValue = "false",
+ description = {"List all resolver services."},
+ required = false)
+ boolean resolvers = false;
+
+ @CommandLine.Option(
+ names = {"-rn", "--runtimes"},
+ defaultValue = "false",
+ description = {"List all runtime services."},
+ required = false)
+ boolean runtimes = false;
+
+ @CommandLine.Option(
+ names = {"-rr", "--resources"},
+ defaultValue = "false",
+ description = {"List all resource services."},
+ required = false)
+ boolean resources = false;
+
+ @CommandLine.Option(
+ names = {"-c", "--community"},
+ defaultValue = "false",
+ description = {"List all community services."},
+ required = false)
+ boolean community = false;
+
+ @Override
+ public void run() {
+
+ PrintWriter out = commandSpec.commandLine().getOut();
+
+ /*
+ * TODO Print generic info about the service scope and the discovery strategy
+ * installed.
+ */
+
+ for (var serviceType :
+ new KlabService.Type[] {
+ KlabService.Type.REASONER,
+ KlabService.Type.RESOURCES,
+ KlabService.Type.RESOLVER,
+ KlabService.Type.RUNTIME,
+ KlabService.Type.COMMUNITY,
+ KlabService.Type.ENGINE
+ }) {
+
+ if (serviceType == KlabService.Type.ENGINE) {
+ // TODO describe the engine
+ } else {
+
+ boolean first = true;
+ for (var service :
+ KlabCLI.INSTANCE.engine().serviceScope().getServices(serviceType.classify())) {
+
+ if (reasoners && serviceType != KlabService.Type.REASONER
+ || resolvers && serviceType != KlabService.Type.RESOLVER
+ || resources && serviceType != KlabService.Type.RESOURCES
+ || runtimes && serviceType != KlabService.Type.RUNTIME
+ || community && serviceType != KlabService.Type.COMMUNITY) {
+ continue;
+ }
+
+ /*
+ * TODO tag each service with a keyword or parameter so that it can be easily
+ * referenced using connect. Keep the services dictionary in the superclass.
+ */
+
+ if (first) {
+ // out.println(serviceType);
+ // TODO number for selection; highlight the name of the "current" service in
+ // each category
+ out.println(
+ " "
+ + Utils.Paths.getLast(service.getClass().getName(), '.')
+ + ": "
+ + service.getServiceName()
+ + " "
+ + " ["
+ + (service.status().isAvailable() ? "available" : "not available")
+ + (service instanceof ServiceClient client && client.isLocal()
+ ? "," + "local"
+ : "")
+ + "] "
+ + service.getUrl()
+ + ServicesAPI.CAPABILITIES);
+ if (verbose) {
+ out.println(
+ Utils.Strings.indent(
+ Utils.Json.printAsJson(
+ service.capabilities(KlabCLI.INSTANCE.engine().getUsers().get(0))),
+ 6));
}
+ }
+ first = false;
}
+ }
}
-
- public static class ServiceHandler {
-
- /**
- * TODO add optional arguments to fill in the entire request on the CLI by passing the schema id and
- * parameters. The help should list all parameters with a description (currently missing).
- *
- * @param serviceType
- */
- protected static void importFromSchema(KlabService.Type serviceType, boolean help,
- String suggestedUrn, java.util.List arguments) {
-
- if (help) {
-
- return;
- }
-
- var service = KlabCLI.INSTANCE.user().getService(serviceType.classify());
- if (service != null) {
- KlabCLI.INSTANCE.importWithSchema(service, suggestedUrn, arguments);
- }
- }
-
- /**
- * TODO add optional arguments to fill in the entire request on the CLI by passing the schema id and
- * parameters. The help should list all parameters with a description (currently missing).
- *
- * @param serviceType
- */
- protected static void exportFromSchema(KlabService.Type serviceType, boolean help,
- java.util.List arguments) {
-
- if (help) {
- return;
- }
-
- var service = KlabCLI.INSTANCE.user().getService(serviceType.classify());
- if (service != null) {
- KlabCLI.INSTANCE.exportWithSchema(service, arguments);
- }
- }
-
-
+ }
+
+ public static class ServiceHandler {
+
+ /**
+ * TODO add optional arguments to fill in the entire request on the CLI by passing the schema id
+ * and parameters. The help should list all parameters with a description (currently missing).
+ *
+ * @param serviceType
+ */
+ protected static void importFromSchema(
+ KlabService.Type serviceType,
+ boolean help,
+ String suggestedUrn,
+ java.util.List arguments) {
+
+ if (help) {
+
+ return;
+ }
+
+ var service = KlabCLI.INSTANCE.user().getService(serviceType.classify());
+ if (service != null) {
+ KlabCLI.INSTANCE.importWithSchema(service, suggestedUrn, arguments);
+ }
}
- // TODO help should be custom and show the available schemata
- // TODO enable inline definitions
- @CommandLine.Command(name = "resources",
- subcommands = {Resources.Import.class, Resources.Export.class},
- mixinStandardHelpOptions = true,
- description = {"Connect to an " + "available " + "service", "Makes the service " +
- "available" + " for " + "requests."})
- public static class Resources extends ServiceHandler {
-
- @CommandLine.Option(names = {"-h", "--help"},
- defaultValue = "false",
- description = {"Display available import schemata"},
- required = false)
- boolean help = false;
-
- @CommandLine.Command(name = "import",
- mixinStandardHelpOptions = false,
- description = {"Connect to an " + "available " + "service", "Makes the service" +
- " available" + " for " + "requests."})
- public static class Import implements Runnable {
-
- @CommandLine.Option(names = {"-h", "--help"},
- defaultValue = "false",
- description = {"Display available import schemata"},
- required = false)
- boolean help = false;
-
- @CommandLine.Option(names = {"-u", "--urn"},
- defaultValue = "X:X:X:X",
- description = {"Pass suggested URN for import (result may differ)"},
- required = false)
- String urn;
-
- @CommandLine.Parameters
- java.util.List arguments;
-
- @Override
- public void run() {
- importFromSchema(KlabService.Type.RESOURCES, help, urn, arguments);
- }
- }
-
- @CommandLine.Command(name = "export",
- mixinStandardHelpOptions = false,
- description = {"Connect to an " + "available " + "service", "Makes the service" +
- " available" + " for " + "requests."})
- public static class Export implements Runnable {
-
- @CommandLine.Option(names = {"-h", "--help"},
- defaultValue = "false",
- description = {"Display available import schemata"},
- required = false)
- boolean help = false;
-
- @CommandLine.Parameters
- java.util.List arguments;
-
- @Override
- public void run() {
- exportFromSchema(KlabService.Type.RESOURCES, help, arguments);
- }
- }
+ /**
+ * TODO add optional arguments to fill in the entire request on the CLI by passing the schema id
+ * and parameters. The help should list all parameters with a description (currently missing).
+ *
+ * @param serviceType
+ */
+ protected static void exportFromSchema(
+ KlabService.Type serviceType, boolean help, java.util.List arguments) {
+
+ if (help) {
+ return;
+ }
+
+ var service = KlabCLI.INSTANCE.user().getService(serviceType.classify());
+ if (service != null) {
+ KlabCLI.INSTANCE.exportWithSchema(service, arguments);
+ }
}
-
- // TODO help should be custom and show the available schemata
- // TODO enable inline definitions
- @CommandLine.Command(name = "runtime",
- subcommands = {Runtime.Import.class, Runtime.Export.class},
- mixinStandardHelpOptions = true,
- description = {"Connect to an " + "available " + "service", "Makes the service " +
- "available" + " for " + "requests."})
- static class Runtime extends ServiceHandler {
-
- @CommandLine.Command(name = "import",
- mixinStandardHelpOptions = false,
- description = {"Connect to an " + "available " + "service", "Makes the service" +
- " available" + " for " + "requests."})
- public static class Import implements Runnable {
-
- @CommandLine.Option(names = {"-h", "--help"},
- defaultValue = "false",
- description = {"Display available import schemata"},
- required = false)
- boolean help = false;
-
- @CommandLine.Option(names = {"-u", "--urn"},
- defaultValue = "X:X:X:X",
- description = {"Pass suggested URN for import (result may differ)"},
- required = false)
- String urn;
-
- @CommandLine.Parameters
- java.util.List arguments;
-
- @Override
- public void run() {
- importFromSchema(KlabService.Type.RUNTIME, help, urn, arguments);
- }
- }
-
- @CommandLine.Command(name = "export",
- mixinStandardHelpOptions = false,
- description = {"Connect to an " + "available " + "service", "Makes the service" +
- " available" + " for " + "requests."})
- public static class Export implements Runnable {
-
- @CommandLine.Option(names = {"-h", "--help"},
- defaultValue = "false",
- description = {"Display available import schemata"},
- required = false)
- boolean help = false;
-
- @CommandLine.Parameters
- java.util.List arguments;
-
- @Override
- public void run() {
- exportFromSchema(KlabService.Type.RUNTIME, help, arguments);
- }
- }
-
+ }
+
+ // TODO help should be custom and show the available schemata
+ // TODO enable inline definitions
+ @CommandLine.Command(
+ name = "resources",
+ subcommands = {Resources.Import.class, Resources.Export.class},
+ mixinStandardHelpOptions = true,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service " + "available" + " for " + "requests."
+ })
+ public static class Resources extends ServiceHandler {
+
+ @CommandLine.Option(
+ names = {"-h", "--help"},
+ defaultValue = "false",
+ description = {"Display available import schemata"},
+ required = false)
+ boolean help = false;
+
+ @CommandLine.Command(
+ name = "import",
+ mixinStandardHelpOptions = false,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service" + " available" + " for " + "requests."
+ })
+ public static class Import implements Runnable {
+
+ @CommandLine.Option(
+ names = {"-h", "--help"},
+ defaultValue = "false",
+ description = {"Display available import schemata"},
+ required = false)
+ boolean help = false;
+
+ @CommandLine.Option(
+ names = {"-u", "--urn"},
+ defaultValue = "X:X:X:X",
+ description = {"Pass suggested URN for import (result may differ)"},
+ required = false)
+ String urn;
+
+ @CommandLine.Parameters java.util.List arguments;
+
+ @Override
+ public void run() {
+ importFromSchema(KlabService.Type.RESOURCES, help, urn, arguments);
+ }
}
+ @CommandLine.Command(
+ name = "export",
+ mixinStandardHelpOptions = false,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service" + " available" + " for " + "requests."
+ })
+ public static class Export implements Runnable {
+
+ @CommandLine.Option(
+ names = {"-h", "--help"},
+ defaultValue = "false",
+ description = {"Display available import schemata"},
+ required = false)
+ boolean help = false;
+
+ @CommandLine.Parameters java.util.List arguments;
+
+ @Override
+ public void run() {
+ exportFromSchema(KlabService.Type.RESOURCES, help, arguments);
+ }
+ }
+ }
+
+ // TODO help should be custom and show the available schemata
+ // TODO enable inline definitions
+ @CommandLine.Command(
+ name = "runtime",
+ subcommands = {Runtime.Import.class, Runtime.Export.class},
+ mixinStandardHelpOptions = true,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service " + "available" + " for " + "requests."
+ })
+ static class Runtime extends ServiceHandler {
+
+ @CommandLine.Command(
+ name = "import",
+ mixinStandardHelpOptions = false,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service" + " available" + " for " + "requests."
+ })
+ public static class Import implements Runnable {
+
+ @CommandLine.Option(
+ names = {"-h", "--help"},
+ defaultValue = "false",
+ description = {"Display available import schemata"},
+ required = false)
+ boolean help = false;
+
+ @CommandLine.Option(
+ names = {"-u", "--urn"},
+ defaultValue = "X:X:X:X",
+ description = {"Pass suggested URN for import (result may differ)"},
+ required = false)
+ String urn;
+
+ @CommandLine.Parameters java.util.List arguments;
+
+ @Override
+ public void run() {
+ importFromSchema(KlabService.Type.RUNTIME, help, urn, arguments);
+ }
+ }
- @CommandLine.Command(name = "connect",
- mixinStandardHelpOptions = true,
- description = {"Connect to an " + "available " + "service", "Makes the service " +
- "available" + " for " + "requests."})
- static class Connect implements Runnable {
-
- @CommandLine.Option(names = {"-d", "--default"},
- defaultValue = "false",
- description = {"Make the connected service also the default to answer requests."},
- required = false)
- boolean makeDefault = false;
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
-
- }
-
+ @CommandLine.Command(
+ name = "export",
+ mixinStandardHelpOptions = false,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service" + " available" + " for " + "requests."
+ })
+ public static class Export implements Runnable {
+
+ @CommandLine.Option(
+ names = {"-h", "--help"},
+ defaultValue = "false",
+ description = {"Display available import schemata"},
+ required = false)
+ boolean help = false;
+
+ @CommandLine.Parameters java.util.List arguments;
+
+ @Override
+ public void run() {
+ exportFromSchema(KlabService.Type.RUNTIME, help, arguments);
+ }
}
+ }
+
+ @CommandLine.Command(
+ name = "connect",
+ mixinStandardHelpOptions = true,
+ description = {
+ "Connect to an " + "available " + "service",
+ "Makes the service " + "available" + " for " + "requests."
+ })
+ static class Connect implements Runnable {
+
+ @CommandLine.Option(
+ names = {"-d", "--default"},
+ defaultValue = "false",
+ description = {"Make the connected service also the default to answer requests."},
+ required = false)
+ boolean makeDefault = false;
@Override
- public void servicesConfigurationChanged(KlabService.ServiceCapabilities service) {
+ public void run() {
+ // TODO Auto-generated method stub
}
+ }
- @Override
- public void notifyServiceStatus(KlabService.ServiceStatus status) {
+ @Override
+ public void servicesConfigurationChanged(KlabService.ServiceCapabilities service) {}
- }
+ @Override
+ public void notifyServiceStatus(KlabService.ServiceStatus status) {}
- @Override
- public void engineStatusChanged(Engine.Status status) {
- this.status.set(status);
- }
+ @Override
+ public void engineStatusChanged(Engine.Status status) {
+ this.status.set(status);
+ }
}
diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/CRUDOperation.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/CRUDOperation.java
index b2fb39a06..65f077e94 100644
--- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/CRUDOperation.java
+++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/CRUDOperation.java
@@ -1,7 +1,9 @@
package org.integratedmodelling.klab.api.authentication;
public enum CRUDOperation {
-
- CREATE, DELETE, UPDATE, UPDATE_METADATA, READ
-
+ CREATE,
+ DELETE,
+ UPDATE,
+ UPDATE_METADATA,
+ READ
}
diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/ResourcePrivileges.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/ResourcePrivileges.java
index 40de36c32..913aef91d 100644
--- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/ResourcePrivileges.java
+++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/authentication/ResourcePrivileges.java
@@ -11,212 +11,208 @@
import java.util.Set;
/**
- * Permissions in k.LAB are either "*" for public and/or a list of comma-separated groups (uppercase) and/or
- * usernames (lowercase). An empty permission string means "owner only" (and possibly admin, left to
- * implementations). Prefixing either with a ! denies the permission for the user or group (supposedly to
- * narrow a previous more general one: e.g. *,!BADGUYS).
- *
- * This class parses a permission string and has methods to establish authorization given a username and a set
- * of groups.
+ * Permissions in k.LAB are either "*" for public and/or a list of comma-separated groups
+ * (uppercase) and/or usernames (lowercase). An empty permission string means "owner only" (and
+ * possibly admin, left to implementations). Prefixing either with a ! denies the permission for the
+ * user or group (supposedly to narrow a previous more general one: e.g. *,!BADGUYS).
+ *
+ *
This class parses a permission string and has methods to establish authorization given a
+ * username and a set of groups.
*/
public class ResourcePrivileges implements Serializable {
- private boolean isPublic;
- private Set allowedGroups = new HashSet<>();
- private Set excludedGroups = new HashSet<>();
- private Set allowedUsers = new HashSet<>();
- private Set excludedUsers = new HashSet<>();
- private Set allowedServices = new HashSet<>();
-
-
- /**
- * Use this constant instead of building an object to define publicly accessible resources.
- */
- static public ResourcePrivileges PUBLIC;
-
- static {
- PUBLIC = new ResourcePrivileges();
- PUBLIC.setPublic(true);
- }
-
- public ResourcePrivileges() {
- }
-
- private ResourcePrivileges(String s) {
- if (s != null && !s.isEmpty()) {
- String[] ss = s.split(",");
- for (String token : ss) {
- token = token.trim();
- if ("*".equals(token)) {
- this.isPublic = true;
- } else {
- if (!token.equals(token.toUpperCase())) {
- // lowercase
- if (token.startsWith("!")) {
- this.excludedUsers.add(token.substring(1));
- } else {
- this.allowedUsers.add(token);
- }
- } else {
- if (token.startsWith("!")) {
- this.excludedGroups.add(token.substring(1));
- } else {
- this.allowedGroups.add(token);
- }
- }
- }
+ private boolean isPublic;
+ private Set allowedGroups = new HashSet<>();
+ private Set excludedGroups = new HashSet<>();
+ private Set allowedUsers = new HashSet<>();
+ private Set excludedUsers = new HashSet<>();
+ private Set allowedServices = new HashSet<>();
+
+ /** Use this constant instead of building an object to define publicly accessible resources. */
+ public static ResourcePrivileges PUBLIC;
+
+ static {
+ PUBLIC = new ResourcePrivileges();
+ PUBLIC.setPublic(true);
+ }
+
+ public ResourcePrivileges() {}
+
+ private ResourcePrivileges(String s) {
+ if (s != null && !s.isEmpty()) {
+ String[] ss = s.split(",");
+ for (String token : ss) {
+ token = token.trim();
+ if ("*".equals(token)) {
+ this.isPublic = true;
+ } else {
+ if (!token.equals(token.toUpperCase())) {
+ // lowercase
+ if (token.startsWith("!")) {
+ this.excludedUsers.add(token.substring(1));
+ } else {
+ this.allowedUsers.add(token);
}
- }
- }
-
- /**
- * Create an empty permission object (to add to if wished). Its toString() method will produce the
- * permission string. Note that empty permissions don't prevent access to the owner and (possibly) a root
- * administrator.
- *
- * @return
- */
- public static ResourcePrivileges empty() {
- return new ResourcePrivileges(null);
- }
-
- /**
- * Create a permission object from a string.
- *
- * @param permissions
- * @return
- */
- public static ResourcePrivileges create(String permissions) {
- return new ResourcePrivileges(permissions);
- }
-
- public boolean checkAuthorization(Scope scope) {
-
- // Only way to get a ServiceScope here is if the same service is requesting the resource. This also
- // covers scope == null, which is OK if the resource is public.
- if (isPublic || scope instanceof ServiceScope) {
- return true;
- }
-
- if (scope instanceof UserScope userScope) {
- return checkAuthorization(userScope.getUser().getUsername(), userScope.getUser().getGroups());
- }
-
- return true;
- }
-
- public boolean checkAuthorization(String username, Collection groups) {
- boolean authorized = isPublic;
- if (!authorized) {
- authorized = allowedUsers.contains(username);
- }
- if (!authorized) {
- for (var group : groups) {
- if (allowedGroups.contains(group.getName())) {
- authorized = true;
- break;
- }
+ } else {
+ if (token.startsWith("!")) {
+ this.excludedGroups.add(token.substring(1));
+ } else {
+ this.allowedGroups.add(token);
}
+ }
}
-
- boolean prevented = false;
- if (authorized) {
- // check if prevented
- prevented = excludedUsers.contains(username);
- if (!prevented) {
- for (var group : groups) {
- if (excludedGroups.contains(group.getName())) {
- prevented = true;
- break;
- }
- }
- }
+ }
+ }
+ }
+
+ /**
+ * Create an empty permission object (to add to if wished). Its toString() method will produce the
+ * permission string. Note that empty permissions don't prevent access to the owner and (possibly)
+ * a root administrator.
+ *
+ * @return
+ */
+ public static ResourcePrivileges empty() {
+ return new ResourcePrivileges(null);
+ }
+
+ /**
+ * Create a permission object from a string.
+ *
+ * @param permissions
+ * @return
+ */
+ public static ResourcePrivileges create(String permissions) {
+ return new ResourcePrivileges(permissions);
+ }
+
+ public boolean checkAuthorization(Scope scope) {
+
+ // Only way to get a ServiceScope here is if the same service is requesting the resource. This
+ // also
+ // covers scope == null, which is OK if the resource is public.
+ if (isPublic || scope instanceof ServiceScope) {
+ return true;
+ }
+
+ if (scope instanceof UserScope userScope) {
+ return checkAuthorization(userScope.getUser().getUsername(), userScope.getUser().getGroups());
+ }
+
+ return true;
+ }
+
+ public boolean checkAuthorization(String username, Collection groups) {
+ boolean authorized = isPublic;
+ if (!authorized) {
+ authorized = allowedUsers.contains(username);
+ }
+ if (!authorized) {
+ for (var group : groups) {
+ if (allowedGroups.contains(group.getName())) {
+ authorized = true;
+ break;
}
-
- return authorized && !prevented;
- }
-
- public void setAllowedGroups(Set allowedGroups) {
- this.allowedGroups = allowedGroups;
- }
-
- public void setExcludedGroups(Set excludedGroups) {
- this.excludedGroups = excludedGroups;
- }
-
- public void setAllowedUsers(Set allowedUsers) {
- this.allowedUsers = allowedUsers;
- }
-
- public void setExcludedUsers(Set excludedUsers) {
- this.excludedUsers = excludedUsers;
- }
-
- public boolean isPublic() {
- return isPublic;
- }
-
- public void setPublic(boolean isPublic) {
- this.isPublic = isPublic;
- }
-
- public Set getAllowedGroups() {
- return allowedGroups;
- }
-
- public Set getExcludedGroups() {
- return excludedGroups;
- }
-
- public Set getAllowedUsers() {
- return allowedUsers;
- }
-
- public Set getExcludedUsers() {
- return excludedUsers;
- }
-
- @Override
- public String toString() {
- return encode();
- }
-
- private String encode() {
- StringBuffer buffer = new StringBuffer(256);
- if (isPublic)
- buffer.append("*");
- for (String group : allowedGroups) {
- buffer.append(buffer.isEmpty() ? "" : ",").append(group);
- }
- for (String user : allowedUsers) {
- buffer.append(buffer.isEmpty() ? "" : ",").append(user);
- }
- for (String group : excludedGroups) {
- buffer.append(buffer.isEmpty() ? "" : ",").append("!").append(group);
- }
- for (String user : excludedUsers) {
- buffer.append(buffer.isEmpty() ? "" : ",").append("!").append(user);
+ }
+ }
+
+ boolean prevented = false;
+ if (authorized) {
+ // check if prevented
+ prevented = excludedUsers.contains(username);
+ if (!prevented) {
+ for (var group : groups) {
+ if (excludedGroups.contains(group.getName())) {
+ prevented = true;
+ break;
+ }
}
- return buffer.toString();
- }
-
- public Set getAllowedServices() {
- return allowedServices;
- }
-
- public void setAllowedServices(Set allowedServices) {
- this.allowedServices = allowedServices;
- }
-
- /**
- * This is returned by the API and should only show the privileges that are not beyond the passed scope's
- * pay grade.
- *
- * @param scope
- * @return
- */
- public ResourcePrivileges asSeenByScope(Scope scope) {
- // TODO filter privileges to those visible by the scope
- return this;
- }
+ }
+ }
+
+ return authorized && !prevented;
+ }
+
+ public void setAllowedGroups(Set allowedGroups) {
+ this.allowedGroups = allowedGroups;
+ }
+
+ public void setExcludedGroups(Set excludedGroups) {
+ this.excludedGroups = excludedGroups;
+ }
+
+ public void setAllowedUsers(Set allowedUsers) {
+ this.allowedUsers = allowedUsers;
+ }
+
+ public void setExcludedUsers(Set excludedUsers) {
+ this.excludedUsers = excludedUsers;
+ }
+
+ public boolean isPublic() {
+ return isPublic;
+ }
+
+ public void setPublic(boolean isPublic) {
+ this.isPublic = isPublic;
+ }
+
+ public Set getAllowedGroups() {
+ return allowedGroups;
+ }
+
+ public Set getExcludedGroups() {
+ return excludedGroups;
+ }
+
+ public Set getAllowedUsers() {
+ return allowedUsers;
+ }
+
+ public Set getExcludedUsers() {
+ return excludedUsers;
+ }
+
+ @Override
+ public String toString() {
+ return encode();
+ }
+
+ private String encode() {
+ StringBuffer buffer = new StringBuffer(256);
+ if (isPublic) buffer.append("*");
+ for (String group : allowedGroups) {
+ buffer.append(buffer.isEmpty() ? "" : ",").append(group);
+ }
+ for (String user : allowedUsers) {
+ buffer.append(buffer.isEmpty() ? "" : ",").append(user);
+ }
+ for (String group : excludedGroups) {
+ buffer.append(buffer.isEmpty() ? "" : ",").append("!").append(group);
+ }
+ for (String user : excludedUsers) {
+ buffer.append(buffer.isEmpty() ? "" : ",").append("!").append(user);
+ }
+ return buffer.toString();
+ }
+
+ public Set getAllowedServices() {
+ return allowedServices;
+ }
+
+ public void setAllowedServices(Set allowedServices) {
+ this.allowedServices = allowedServices;
+ }
+
+ /**
+ * This is returned by the API and should only show the privileges that are not beyond the passed
+ * scope's pay grade.
+ *
+ * @param scope
+ * @return
+ */
+ public ResourcePrivileges asSeenByScope(Scope scope) {
+ // TODO filter privileges to those visible by the scope
+ return this;
+ }
}
diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/SemanticType.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/SemanticType.java
index b92768e99..d5c7c5da5 100644
--- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/SemanticType.java
+++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/SemanticType.java
@@ -11,544 +11,555 @@
* @author ferdinando.villa
*/
public enum SemanticType {
- /**
- *
- */
- OBSERVABLE,
- /**
- * Predicates are traits, roles and domains.
- */
- PREDICATE,
- /**
- *
- */
- QUALITY,
- /**
- *
- */
- PROCESS,
- /**
- *
- */
- SUBJECT,
- /**
- *
- */
- EVENT,
- /**
- *
- */
- RELATIONSHIP,
- /**
- *
- */
- EXTENSIVE,
- /**
- *
- */
- INTENSIVE,
- /**
- *
- */
- TRAIT,
- /**
- *
- */
- IDENTITY,
- /**
- *
- */
- ATTRIBUTE,
- /**
- *
- */
- REALM,
- /**
- *
- */
- SUBJECTIVE,
- /**
- *
- */
- INTERNAL,
- /**
- *
- */
- ROLE,
- /**
- *
- */
- DENIABLE,
- /**
- *
- */
- CONFIGURATION,
- /**
- *
- */
- ABSTRACT,
- /**
- *
- */
- NOTHING,
- /**
- *
- */
- ORDERING,
- /**
- *
- */
- CLASS,
- /**
- *
- */
- QUANTITY,
- /**
- *
- */
- DOMAIN,
- /**
- *
- */
- ENERGY,
- /**
- *
- */
- ENTROPY,
- /**
- *
- */
- LENGTH,
- /**
- *
- */
- MASS,
- /**
- *
- */
- VOLUME,
- /**
- *
- */
- WEIGHT,
- /**
- *
- */
- MONEY,
- /**
- *
- */
- DURATION,
- /**
- *
- */
- AREA,
- /**
- *
- */
- ACCELERATION,
- /**
- *
- */
- PRIORITY,
- /**
- *
- */
- ELECTRIC_POTENTIAL,
- /**
- *
- */
- CHARGE,
- /**
- *
- */
- RESISTANCE,
- /**
- *
- */
- RESISTIVITY,
- /**
- *
- */
- PRESSURE,
- /**
- *
- */
- ANGLE,
- /**
- *
- */
- VELOCITY,
- /**
- *
- */
- TEMPERATURE,
- /**
- *
- */
- VISCOSITY,
- /**
- *
- */
- AGENT,
- /**
- *
- */
- FUNCTIONAL,
- /**
- *
- */
- STRUCTURAL,
- /**
- *
- */
- BIDIRECTIONAL,
- /**
- *
- */
- UNIDIRECTIONAL,
- /**
- *
- */
- DELIBERATIVE,
- /**
- *
- */
- INTERACTIVE,
- /**
- *
- */
- REACTIVE,
- /**
- *
- */
- DIRECT_OBSERVABLE,
- /**
- *
- */
- COUNTABLE,
- /**
- *
- */
- UNCERTAINTY,
- /**
- *
- */
- PROBABILITY,
- /**
- *
- */
- PROPORTION,
- /**
- *
- */
- PERCENTAGE,
- /**
- *
- */
- NUMEROSITY,
- /**
- *
- */
- DISTANCE,
- /**
- *
- */
- RATIO,
- /**
- *
- */
- VALUE,
- /**
- *
- */
- OCCURRENCE,
- /**
- *
- */
- PRESENCE,
- /**
- *
- */
- EXTENT,
- /**
- *
- */
- MACRO,
- /**
- *
- */
- AMOUNT,
+ /** */
+ OBSERVABLE,
+ /** Predicates are traits, roles and domains. */
+ PREDICATE,
+ /** */
+ QUALITY,
+ /** */
+ PROCESS,
+ /** */
+ SUBJECT,
+ /** */
+ EVENT,
+ /** */
+ RELATIONSHIP,
+ /** */
+ EXTENSIVE,
+ /** */
+ INTENSIVE,
+ /** */
+ TRAIT,
+ /** */
+ IDENTITY,
+ /** */
+ ATTRIBUTE,
+ /** */
+ REALM,
+ /** */
+ SUBJECTIVE,
+ /** */
+ INTERNAL,
+ /** */
+ ROLE,
+ /** */
+ DENIABLE,
+ /** */
+ CONFIGURATION,
+ /** */
+ ABSTRACT,
+ /** */
+ NOTHING,
+ /** */
+ ORDERING,
+ /** */
+ CLASS,
+ /** */
+ QUANTITY,
+ /** */
+ DOMAIN,
+ /** */
+ ENERGY,
+ /** */
+ ENTROPY,
+ /** */
+ LENGTH,
+ /** */
+ MASS,
+ /** */
+ VOLUME,
+ /** */
+ WEIGHT,
+ /** */
+ MONEY,
+ /** */
+ DURATION,
+ /** */
+ AREA,
+ /** */
+ ACCELERATION,
+ /** */
+ PRIORITY,
+ /** */
+ ELECTRIC_POTENTIAL,
+ /** */
+ CHARGE,
+ /** */
+ RESISTANCE,
+ /** */
+ RESISTIVITY,
+ /** */
+ PRESSURE,
+ /** */
+ ANGLE,
+ /** */
+ VELOCITY,
+ /** */
+ TEMPERATURE,
+ /** */
+ VISCOSITY,
+ /** */
+ AGENT,
+ /** */
+ FUNCTIONAL,
+ /** */
+ STRUCTURAL,
+ /** */
+ BIDIRECTIONAL,
+ /** */
+ UNIDIRECTIONAL,
+ /** */
+ DELIBERATIVE,
+ /** */
+ INTERACTIVE,
+ /** */
+ REACTIVE,
+ /** */
+ DIRECT_OBSERVABLE,
+ /** */
+ COUNTABLE,
+ /** */
+ UNCERTAINTY,
+ /** */
+ PROBABILITY,
+ /** */
+ PROPORTION,
+ /** */
+ PERCENTAGE,
+ /** */
+ NUMEROSITY,
+ /** */
+ DISTANCE,
+ /** */
+ RATIO,
+ /** */
+ VALUE,
+ /** */
+ OCCURRENCE,
+ /** */
+ PRESENCE,
+ /** */
+ EXTENT,
+ /** */
+ MACRO,
+ /** */
+ AMOUNT,
- /**
- * Only for concept peers of non-semantic types: this should never appear in a declared concept
- */
- CATEGORY,
- /**
- *
- */
- MAGNITUDE,
- /**
- * A quality that can be quantified numerically
- */
- QUANTIFIABLE,
- /**
- * Reserved for unions built from declarations
- */
- UNION,
- /**
- * Reserved for intersections built from declarations
- */
- INTERSECTION,
- /**
- * Specifier for values; affects validation of currencies
- */
- MONETARY_VALUE,
- /**
- * Makes an attribute a rescaling transformation, which does not preserve observation semantics
- */
- RESCALING,
- /**
- * A process that defines the change of its inherent quality.
- */
- CHANGE,
- /**
- * A quality that describes the speed of change of its inherent quality.
- */
- RATE,
- /**
- * An event that results from a change of value in the inherent quality.
- */
- CHANGED,
- /**
- * A supertype with sealed closure
- */
- SEALED,
- /**
- * Concept that have the syntax of authority references (with the uppercase namespace) get this type even
- * if not recognized by an online authority (in which case they won't have the IDENTITY type but will
- * still have this, so that the syntactic validation won't fail).
- */
- AUTHORITY_IDENTITY;
+ /**
+ * Only for concept peers of non-semantic types: this should never appear in a declared concept
+ */
+ CATEGORY,
+ /** */
+ MAGNITUDE,
+ /** A quality that can be quantified numerically */
+ QUANTIFIABLE,
+ /** Reserved for unions built from declarations */
+ UNION,
+ /** Reserved for intersections built from declarations */
+ INTERSECTION,
+ /** Specifier for values; affects validation of currencies */
+ MONETARY_VALUE,
+ /**
+ * Makes an attribute a rescaling transformation, which does not preserve observation semantics
+ */
+ RESCALING,
+ /** A process that defines the change of its inherent quality. */
+ CHANGE,
+ /** A quality that describes the speed of change of its inherent quality. */
+ RATE,
+ /** An event that results from a change of value in the inherent quality. */
+ CHANGED,
+ /** A supertype with sealed closure */
+ SEALED,
+ /**
+ * Concept that have the syntax of authority references (with the uppercase namespace) get this
+ * type even if not recognized by an online authority (in which case they won't have the IDENTITY
+ * type but will still have this, so that the syntactic validation won't fail).
+ */
+ AUTHORITY_IDENTITY;
- public boolean isNumeric() {
- return CONTINUOUS_QUALITY_TYPES.contains(this);
- }
+ public boolean isNumeric() {
+ return CONTINUOUS_QUALITY_TYPES.contains(this);
+ }
- public boolean isQuality() {
- return ALL_QUALITY_TYPES.contains(this);
- }
+ public boolean isQuality() {
+ return ALL_QUALITY_TYPES.contains(this);
+ }
- public boolean admitsUnits() {
- return this == EXTENSIVE || this == INTENSIVE || this == NUMEROSITY;
- }
+ public boolean admitsUnits() {
+ return this == EXTENSIVE || this == INTENSIVE || this == NUMEROSITY;
+ }
- public boolean admitsCurrency() {
- return this == MONETARY_VALUE;
- }
+ public boolean admitsCurrency() {
+ return this == MONETARY_VALUE;
+ }
- public boolean isSubstantial() {
- return DIRECT_OBSERVABLE_TYPES.contains(this);
- }
+ public boolean isSubstantial() {
+ return DIRECT_OBSERVABLE_TYPES.contains(this);
+ }
- public static boolean isSubstantial(Set type) {
- var set = EnumSet.copyOf(type);
- set.retainAll(DIRECT_OBSERVABLE_TYPES);
- return !set.isEmpty();
- }
+ public static boolean isSubstantial(Set type) {
+ var set = EnumSet.copyOf(type);
+ set.retainAll(DIRECT_OBSERVABLE_TYPES);
+ return !set.isEmpty();
+ }
- public boolean isPredicate() {
- return this == ROLE || TRAIT_TYPES.contains(this);
- }
+ public boolean isPredicate() {
+ return this == ROLE || TRAIT_TYPES.contains(this);
+ }
- public boolean isTrait() {
- return TRAIT_TYPES.contains(this);
- }
+ public boolean isTrait() {
+ return TRAIT_TYPES.contains(this);
+ }
- /**
- * All declarable concept bits set. Each observable AND this must yield a set of size 1.
- */
- public static final EnumSet FUNDAMENTAL_TYPES = EnumSet.of(SemanticType.QUALITY,
- SemanticType.SUBJECT, SemanticType.AGENT, SemanticType.EVENT, SemanticType.CONFIGURATION,
- SemanticType.DOMAIN, SemanticType.RELATIONSHIP, SemanticType.EXTENT, SemanticType.PROCESS,
- SemanticType.ATTRIBUTE, SemanticType.REALM, SemanticType.IDENTITY, SemanticType.ROLE);
+ /** All declarable concept bits set. Each observable AND this must yield a set of size 1. */
+ public static final EnumSet FUNDAMENTAL_TYPES =
+ EnumSet.of(
+ SemanticType.QUALITY,
+ SemanticType.SUBJECT,
+ SemanticType.AGENT,
+ SemanticType.EVENT,
+ SemanticType.CONFIGURATION,
+ SemanticType.DOMAIN,
+ SemanticType.RELATIONSHIP,
+ SemanticType.EXTENT,
+ SemanticType.PROCESS,
+ SemanticType.ATTRIBUTE,
+ SemanticType.REALM,
+ SemanticType.IDENTITY,
+ SemanticType.ROLE);
- public static final EnumSet MODELABLE_TYPES = EnumSet.of(SemanticType.QUALITY,
- SemanticType.SUBJECT, SemanticType.AGENT, SemanticType.EVENT, SemanticType.CONFIGURATION,
- SemanticType.RELATIONSHIP, SemanticType.PROCESS, SemanticType.TRAIT, SemanticType.ROLE,
- SemanticType.DOMAIN);
+ public static final EnumSet MODELABLE_TYPES =
+ EnumSet.of(
+ SemanticType.QUALITY,
+ SemanticType.SUBJECT,
+ SemanticType.AGENT,
+ SemanticType.EVENT,
+ SemanticType.CONFIGURATION,
+ SemanticType.RELATIONSHIP,
+ SemanticType.PROCESS,
+ SemanticType.TRAIT,
+ SemanticType.ROLE,
+ SemanticType.DOMAIN);
- /**
- * These need to be represented in the root domain of the ontology using core derivations. They are all
- * disjoint and concrete. TODO at the moment the OPERATOR_TYPES are not directly linked to core types.
- */
- public static final Set DECLARABLE_TYPES = EnumSet.of(SemanticType.PROPORTION,
- SemanticType.PROBABILITY, SemanticType.DISTANCE, SemanticType.VALUE, SemanticType.OCCURRENCE,
- SemanticType.PRESENCE, SemanticType.UNCERTAINTY, SemanticType.NUMEROSITY, SemanticType.RATE,
- SemanticType.CLASS, SemanticType.QUANTITY, SemanticType.ENERGY, SemanticType.ENTROPY,
- SemanticType.LENGTH, SemanticType.MASS, SemanticType.VOLUME, SemanticType.WEIGHT,
- SemanticType.MONEY, SemanticType.DURATION, SemanticType.AREA, SemanticType.ACCELERATION,
- SemanticType.PRIORITY, SemanticType.ELECTRIC_POTENTIAL, SemanticType.CHARGE,
- SemanticType.IDENTITY, SemanticType.DOMAIN,
- SemanticType.RESISTANCE, SemanticType.RESISTIVITY, SemanticType.PRESSURE, SemanticType.ANGLE,
- SemanticType.VELOCITY, SemanticType.TEMPERATURE, SemanticType.VISCOSITY, SemanticType.RATIO,
- SemanticType.AMOUNT, SemanticType.SUBJECT, SemanticType.AGENT, SemanticType.EVENT,
- SemanticType.RELATIONSHIP, SemanticType.PROCESS, SemanticType.CONFIGURATION, SemanticType.ROLE,
- SemanticType.ATTRIBUTE, SemanticType.REALM, SemanticType.ORDERING);
+ /**
+ * These need to be represented in the root domain of the ontology using core derivations. They
+ * are all disjoint and concrete. TODO at the moment the OPERATOR_TYPES are not directly linked to
+ * core types.
+ */
+ public static final Set DECLARABLE_TYPES =
+ EnumSet.of(
+ SemanticType.PROPORTION,
+ SemanticType.PROBABILITY,
+ SemanticType.DISTANCE,
+ SemanticType.VALUE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.UNCERTAINTY,
+ SemanticType.NUMEROSITY,
+ SemanticType.RATE,
+ SemanticType.CLASS,
+ SemanticType.QUANTITY,
+ SemanticType.ENERGY,
+ SemanticType.ENTROPY,
+ SemanticType.LENGTH,
+ SemanticType.MASS,
+ SemanticType.VOLUME,
+ SemanticType.WEIGHT,
+ SemanticType.MONEY,
+ SemanticType.DURATION,
+ SemanticType.AREA,
+ SemanticType.ACCELERATION,
+ SemanticType.PRIORITY,
+ SemanticType.ELECTRIC_POTENTIAL,
+ SemanticType.CHARGE,
+ SemanticType.IDENTITY,
+ SemanticType.DOMAIN,
+ SemanticType.RESISTANCE,
+ SemanticType.RESISTIVITY,
+ SemanticType.PRESSURE,
+ SemanticType.ANGLE,
+ SemanticType.VELOCITY,
+ SemanticType.TEMPERATURE,
+ SemanticType.VISCOSITY,
+ SemanticType.RATIO,
+ SemanticType.AMOUNT,
+ SemanticType.SUBJECT,
+ SemanticType.AGENT,
+ SemanticType.EVENT,
+ SemanticType.RELATIONSHIP,
+ SemanticType.PROCESS,
+ SemanticType.CONFIGURATION,
+ SemanticType.ROLE,
+ SemanticType.ATTRIBUTE,
+ SemanticType.REALM,
+ SemanticType.ORDERING);
- /**
- * Qualities that are naturally inherent and should not be allowed to have explicit inherency but just
- * context.
- */
- public static final EnumSet INHERENT_QUALITIES = EnumSet.of(SemanticType.PROPORTION,
- SemanticType.PROBABILITY, SemanticType.DISTANCE, SemanticType.VALUE, SemanticType.OCCURRENCE,
- SemanticType.PRESENCE, SemanticType.UNCERTAINTY, SemanticType.NUMEROSITY, SemanticType.RATE);
+ /**
+ * Qualities that are naturally inherent and should not be allowed to have explicit inherency but
+ * just context.
+ */
+ public static final EnumSet INHERENT_QUALITIES =
+ EnumSet.of(
+ SemanticType.PROPORTION,
+ SemanticType.PROBABILITY,
+ SemanticType.DISTANCE,
+ SemanticType.VALUE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.UNCERTAINTY,
+ SemanticType.NUMEROSITY,
+ SemanticType.RATE);
- public static final Set OPERATOR_TYPES = EnumSet.of(SemanticType.CHANGE,
- SemanticType.NUMEROSITY, SemanticType.DISTANCE, /* FIXME MISSING: LEVEL? - no it's an ORDERING
- with a described type */ SemanticType.MAGNITUDE, SemanticType.OCCURRENCE, SemanticType.PRESENCE
- , SemanticType.PROBABILITY, SemanticType.PROPORTION, SemanticType.RATIO, SemanticType.CLASS,
- SemanticType.UNCERTAINTY, SemanticType.VALUE, SemanticType.MONETARY_VALUE);
+ public static final Set OPERATOR_TYPES =
+ EnumSet.of(
+ SemanticType.CHANGE,
+ SemanticType.NUMEROSITY,
+ SemanticType.DISTANCE, /* FIXME MISSING: LEVEL? - no it's an ORDERING
+ with a described type */
+ SemanticType.MAGNITUDE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.PROBABILITY,
+ SemanticType.PROPORTION,
+ SemanticType.RATIO,
+ SemanticType.CLASS,
+ SemanticType.UNCERTAINTY,
+ SemanticType.VALUE,
+ SemanticType.MONETARY_VALUE);
- /**
- * All quality type bits sets (not QUALITY itself). Each quality AND this must yield a set of size 1.
- */
- public static final EnumSet QUALITY_TYPES = EnumSet.of(SemanticType.CLASS,
- SemanticType.QUANTITY, SemanticType.ENERGY, SemanticType.ENTROPY, SemanticType.LENGTH,
- SemanticType.MASS, SemanticType.VOLUME, SemanticType.WEIGHT, SemanticType.MONEY,
- SemanticType.DURATION, SemanticType.AREA, SemanticType.ACCELERATION, SemanticType.PRIORITY,
- SemanticType.ELECTRIC_POTENTIAL, SemanticType.CHARGE, SemanticType.RESISTANCE,
- SemanticType.RESISTIVITY, SemanticType.PRESSURE, SemanticType.ANGLE, SemanticType.VELOCITY,
- SemanticType.TEMPERATURE, SemanticType.VISCOSITY, SemanticType.UNCERTAINTY, SemanticType.RATIO,
- SemanticType.PROPORTION, SemanticType.PROBABILITY, SemanticType.NUMEROSITY,
- SemanticType.DISTANCE, SemanticType.VALUE, SemanticType.MONETARY_VALUE, SemanticType.OCCURRENCE
- , SemanticType.PRESENCE, SemanticType.AMOUNT, SemanticType.RATE);
+ /**
+ * All quality type bits sets (not QUALITY itself). Each quality AND this must yield a set of size
+ * 1.
+ */
+ public static final EnumSet QUALITY_TYPES =
+ EnumSet.of(
+ SemanticType.CLASS,
+ SemanticType.QUANTITY,
+ SemanticType.ENERGY,
+ SemanticType.ENTROPY,
+ SemanticType.LENGTH,
+ SemanticType.MASS,
+ SemanticType.VOLUME,
+ SemanticType.WEIGHT,
+ SemanticType.MONEY,
+ SemanticType.DURATION,
+ SemanticType.AREA,
+ SemanticType.ACCELERATION,
+ SemanticType.PRIORITY,
+ SemanticType.ELECTRIC_POTENTIAL,
+ SemanticType.CHARGE,
+ SemanticType.RESISTANCE,
+ SemanticType.RESISTIVITY,
+ SemanticType.PRESSURE,
+ SemanticType.ANGLE,
+ SemanticType.VELOCITY,
+ SemanticType.TEMPERATURE,
+ SemanticType.VISCOSITY,
+ SemanticType.UNCERTAINTY,
+ SemanticType.RATIO,
+ SemanticType.PROPORTION,
+ SemanticType.PROBABILITY,
+ SemanticType.NUMEROSITY,
+ SemanticType.DISTANCE,
+ SemanticType.VALUE,
+ SemanticType.MONETARY_VALUE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.AMOUNT,
+ SemanticType.RATE);
- /**
- * All quality type bits sets including QUALITY itself. Each quality AND this must yield a set of size 0.
- */
- public static final EnumSet ALL_QUALITY_TYPES = EnumSet.of(SemanticType.CLASS,
- SemanticType.QUALITY, SemanticType.QUANTITY, SemanticType.ENERGY, SemanticType.ENTROPY,
- SemanticType.LENGTH, SemanticType.MASS, SemanticType.VOLUME, SemanticType.WEIGHT,
- SemanticType.MONEY, SemanticType.DURATION, SemanticType.AREA, SemanticType.ACCELERATION,
- SemanticType.PRIORITY, SemanticType.ELECTRIC_POTENTIAL, SemanticType.CHARGE,
- SemanticType.RESISTANCE, SemanticType.RESISTIVITY, SemanticType.PRESSURE, SemanticType.ANGLE,
- SemanticType.VELOCITY, SemanticType.TEMPERATURE, SemanticType.VISCOSITY,
- SemanticType.UNCERTAINTY, SemanticType.RATIO, SemanticType.PROPORTION, SemanticType.PROBABILITY
- , SemanticType.NUMEROSITY, SemanticType.DISTANCE, SemanticType.VALUE, SemanticType.OCCURRENCE,
- SemanticType.PRESENCE, SemanticType.AMOUNT, SemanticType.RATE, SemanticType.MONETARY_VALUE);
+ /**
+ * All quality type bits sets including QUALITY itself. Each quality AND this must yield a set of
+ * size 0.
+ */
+ public static final EnumSet ALL_QUALITY_TYPES =
+ EnumSet.of(
+ SemanticType.CLASS,
+ SemanticType.QUALITY,
+ SemanticType.QUANTITY,
+ SemanticType.ENERGY,
+ SemanticType.ENTROPY,
+ SemanticType.LENGTH,
+ SemanticType.MASS,
+ SemanticType.VOLUME,
+ SemanticType.WEIGHT,
+ SemanticType.MONEY,
+ SemanticType.DURATION,
+ SemanticType.AREA,
+ SemanticType.ACCELERATION,
+ SemanticType.PRIORITY,
+ SemanticType.ELECTRIC_POTENTIAL,
+ SemanticType.CHARGE,
+ SemanticType.RESISTANCE,
+ SemanticType.RESISTIVITY,
+ SemanticType.PRESSURE,
+ SemanticType.ANGLE,
+ SemanticType.VELOCITY,
+ SemanticType.TEMPERATURE,
+ SemanticType.VISCOSITY,
+ SemanticType.UNCERTAINTY,
+ SemanticType.RATIO,
+ SemanticType.PROPORTION,
+ SemanticType.PROBABILITY,
+ SemanticType.NUMEROSITY,
+ SemanticType.DISTANCE,
+ SemanticType.VALUE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.AMOUNT,
+ SemanticType.RATE,
+ SemanticType.MONETARY_VALUE);
- /**
- * All qualities that are expressed through a continuous numeric state.
- */
- public static final EnumSet CONTINUOUS_QUALITY_TYPES = EnumSet.of(SemanticType.QUANTITY,
- SemanticType.ENERGY, SemanticType.ENTROPY, SemanticType.LENGTH, SemanticType.MASS,
- SemanticType.VOLUME, SemanticType.WEIGHT, SemanticType.MONEY, SemanticType.DURATION,
- SemanticType.AREA, SemanticType.ACCELERATION, SemanticType.PRIORITY,
- SemanticType.ELECTRIC_POTENTIAL, SemanticType.CHARGE, SemanticType.RESISTANCE,
- SemanticType.RESISTIVITY, SemanticType.PRESSURE, SemanticType.ANGLE, SemanticType.VELOCITY,
- SemanticType.TEMPERATURE, SemanticType.VISCOSITY, SemanticType.UNCERTAINTY, SemanticType.RATIO,
- SemanticType.PROPORTION, SemanticType.PROBABILITY, SemanticType.NUMEROSITY,
- SemanticType.DISTANCE, SemanticType.VALUE, SemanticType.OCCURRENCE, SemanticType.PRESENCE,
- SemanticType.AMOUNT, SemanticType.MAGNITUDE, SemanticType.RATE, SemanticType.MONETARY_VALUE);
+ /** All qualities that are expressed through a continuous numeric state. */
+ public static final EnumSet CONTINUOUS_QUALITY_TYPES =
+ EnumSet.of(
+ SemanticType.QUANTITY,
+ SemanticType.ENERGY,
+ SemanticType.ENTROPY,
+ SemanticType.LENGTH,
+ SemanticType.MASS,
+ SemanticType.VOLUME,
+ SemanticType.WEIGHT,
+ SemanticType.MONEY,
+ SemanticType.DURATION,
+ SemanticType.AREA,
+ SemanticType.ACCELERATION,
+ SemanticType.PRIORITY,
+ SemanticType.ELECTRIC_POTENTIAL,
+ SemanticType.CHARGE,
+ SemanticType.RESISTANCE,
+ SemanticType.RESISTIVITY,
+ SemanticType.PRESSURE,
+ SemanticType.ANGLE,
+ SemanticType.VELOCITY,
+ SemanticType.TEMPERATURE,
+ SemanticType.VISCOSITY,
+ SemanticType.UNCERTAINTY,
+ SemanticType.RATIO,
+ SemanticType.PROPORTION,
+ SemanticType.PROBABILITY,
+ SemanticType.NUMEROSITY,
+ SemanticType.DISTANCE,
+ SemanticType.VALUE,
+ SemanticType.OCCURRENCE,
+ SemanticType.PRESENCE,
+ SemanticType.AMOUNT,
+ SemanticType.MAGNITUDE,
+ SemanticType.RATE,
+ SemanticType.MONETARY_VALUE);
- /**
- * All direct observables
- */
- public final static EnumSet DIRECT_OBSERVABLE_TYPES =
- EnumSet.of(SemanticType.DIRECT_OBSERVABLE, SemanticType.SUBJECT, SemanticType.AGENT,
- SemanticType.EVENT, SemanticType.RELATIONSHIP, SemanticType.PROCESS,
- SemanticType.CONFIGURATION, SemanticType.COUNTABLE, /* FIXME ??? */SemanticType.ABSTRACT);
+ /** All direct observables */
+ public static final EnumSet DIRECT_OBSERVABLE_TYPES =
+ EnumSet.of(
+ SemanticType.DIRECT_OBSERVABLE,
+ SemanticType.SUBJECT,
+ SemanticType.AGENT,
+ SemanticType.EVENT,
+ SemanticType.RELATIONSHIP,
+ SemanticType.PROCESS,
+ SemanticType.CONFIGURATION,
+ SemanticType.COUNTABLE, /* FIXME ??? */
+ SemanticType.ABSTRACT);
- /**
- * All base observables
- */
- public final static EnumSet BASE_OBSERVABLE_TYPES = EnumSet.of(SemanticType.SUBJECT,
- SemanticType.EVENT, SemanticType.RELATIONSHIP, SemanticType.PROCESS, SemanticType.QUALITY,
- SemanticType.AGENT);
+ /** All base observables */
+ public static final EnumSet BASE_OBSERVABLE_TYPES =
+ EnumSet.of(
+ SemanticType.SUBJECT,
+ SemanticType.EVENT,
+ SemanticType.RELATIONSHIP,
+ SemanticType.PROCESS,
+ SemanticType.QUALITY,
+ SemanticType.AGENT);
- /**
- * Everything we can write a model for
- */
- public final static EnumSet BASE_MODELABLE_TYPES = EnumSet.of(SemanticType.SUBJECT,
- SemanticType.EVENT, SemanticType.RELATIONSHIP, SemanticType.PROCESS, SemanticType.QUALITY,
- SemanticType.AGENT, SemanticType.TRAIT, SemanticType.CONFIGURATION);
+ /** Everything we can write a model for */
+ public static final EnumSet BASE_MODELABLE_TYPES =
+ EnumSet.of(
+ SemanticType.SUBJECT,
+ SemanticType.EVENT,
+ SemanticType.RELATIONSHIP,
+ SemanticType.PROCESS,
+ SemanticType.QUALITY,
+ SemanticType.AGENT,
+ SemanticType.TRAIT,
+ SemanticType.CONFIGURATION);
- /**
- * All trait type bits set (not TRAIT itself). Each trait AND this must yield a set of size 1.
- */
- public static final EnumSet TRAIT_TYPES = EnumSet.of(SemanticType.ATTRIBUTE,
- SemanticType.REALM, SemanticType.IDENTITY);
+ /** All trait type bits set (not TRAIT itself). Each trait AND this must yield a set of size 1. */
+ public static final EnumSet TRAIT_TYPES =
+ EnumSet.of(SemanticType.ATTRIBUTE, SemanticType.REALM, SemanticType.IDENTITY);
- /**
- * All trait type bits set (including TRAIT itself). Each trait AND this must yield a set of size 1.
- */
- public static final EnumSet ALL_TRAIT_TYPES = EnumSet.of(SemanticType.ATTRIBUTE,
- SemanticType.REALM, SemanticType.IDENTITY, SemanticType.TRAIT);
+ /**
+ * All trait type bits set (including TRAIT itself). Each trait AND this must yield a set of size
+ * 1.
+ */
+ public static final EnumSet ALL_TRAIT_TYPES =
+ EnumSet.of(
+ SemanticType.ATTRIBUTE, SemanticType.REALM, SemanticType.IDENTITY, SemanticType.TRAIT);
- public static SemanticType fundamentalType(Collection types) {
+ public static SemanticType fundamentalType(Collection types) {
- Set t = EnumSet.copyOf(types);
- t.retainAll(FUNDAMENTAL_TYPES);
- if (t.size() == 1) {
- return t.iterator().next();
- }
- t = EnumSet.copyOf(types);
- t.retainAll(TRAIT_TYPES);
- if (t.size() == 1) {
- return t.iterator().next();
- }
- if (types.contains(ROLE)) {
- return ROLE;
- }
- return NOTHING;
+ Set t = EnumSet.copyOf(types);
+ t.retainAll(FUNDAMENTAL_TYPES);
+ if (t.size() == 1) {
+ return t.iterator().next();
}
-
- public static boolean isNumeric(Set semantics) {
- EnumSet set = EnumSet.copyOf(semantics);
- set.retainAll(CONTINUOUS_QUALITY_TYPES);
- return !set.isEmpty();
+ t = EnumSet.copyOf(types);
+ t.retainAll(TRAIT_TYPES);
+ if (t.size() == 1) {
+ return t.iterator().next();
}
+ if (types.contains(ROLE)) {
+ return ROLE;
+ }
+ return NOTHING;
+ }
- static final Color CONCEPT_COLOR_UNKNOWN = new Color(255, 0, 0);
- static final Color CONCEPT_COLOR_VOID = new Color(60, 60, 100);
- static final Color CONCEPT_COLOR_QUALITY = new Color(0, 204, 0);
- static final Color CONCEPT_COLOR_CONFIGURATION = new Color(0, 100, 100);
- static final Color CONCEPT_COLOR_SUBJECT = new Color(153, 76, 0);
- static final Color CONCEPT_COLOR_EVENT = new Color(153, 153, 0);
- static final Color CONCEPT_COLOR_PROCESS = new Color(180, 0, 0);
- static final Color CONCEPT_COLOR_RELATIONSHIP = new Color(210, 170, 0);
- static final Color CONCEPT_COLOR_TRAIT = new Color(0, 102, 204);
- static final Color CONCEPT_COLOR_ROLE = new Color(0, 86, 163);
- static final Color CONCEPT_COLOR_EXTENT = new Color(0, 153, 153);
- static final Color CONCEPT_COLOR_DOMAIN = new Color(220, 220, 103);
+ public static boolean isNumeric(Set semantics) {
+ EnumSet set = EnumSet.copyOf(semantics);
+ set.retainAll(CONTINUOUS_QUALITY_TYPES);
+ return !set.isEmpty();
+ }
- /**
- * Source of truth for the UI color corresponding to different semantic categories.
- *
- * @param semantics
- * @return
- */
- public static Color getColor(Set semantics) {
- Set fundamental = EnumSet.copyOf(semantics);
- fundamental.retainAll(MODELABLE_TYPES);
- Color ret = null;
- if (fundamental.size() == 1) {
- ret = switch (fundamental.iterator().next()) {
- case SUBJECT, AGENT -> CONCEPT_COLOR_SUBJECT;
- case EVENT -> CONCEPT_COLOR_EVENT;
- case DOMAIN -> CONCEPT_COLOR_DOMAIN;
- case RELATIONSHIP -> CONCEPT_COLOR_RELATIONSHIP;
- case PROCESS -> CONCEPT_COLOR_PROCESS;
- case QUALITY -> CONCEPT_COLOR_QUALITY;
- case ROLE -> CONCEPT_COLOR_ROLE;
- case CONFIGURATION -> CONCEPT_COLOR_CONFIGURATION;
- case TRAIT -> CONCEPT_COLOR_TRAIT;
- case EXTENT -> CONCEPT_COLOR_EXTENT;
- default -> null;
- };
- }
- return ret == null ? CONCEPT_COLOR_UNKNOWN : ret;
- }
+ static final Color CONCEPT_COLOR_UNKNOWN = new Color(255, 0, 0);
+ static final Color CONCEPT_COLOR_VOID = new Color(60, 60, 100);
+ static final Color CONCEPT_COLOR_QUALITY = new Color(0, 204, 0);
+ static final Color CONCEPT_COLOR_CONFIGURATION = new Color(0, 100, 100);
+ static final Color CONCEPT_COLOR_SUBJECT = new Color(153, 76, 0);
+ static final Color CONCEPT_COLOR_EVENT = new Color(153, 153, 0);
+ static final Color CONCEPT_COLOR_PROCESS = new Color(116, 0, 0);
+ static final Color CONCEPT_COLOR_RELATIONSHIP = new Color(210, 170, 0);
+ static final Color CONCEPT_COLOR_TRAIT = new Color(0, 102, 204);
+ static final Color CONCEPT_COLOR_ROLE = new Color(0, 86, 163);
+ static final Color CONCEPT_COLOR_EXTENT = new Color(0, 153, 153);
+ static final Color CONCEPT_COLOR_DOMAIN = new Color(220, 220, 103);
+ /**
+ * Source of truth for the UI color corresponding to different semantic categories.
+ *
+ * @param semantics
+ * @return
+ */
+ public static Color getColor(Set semantics) {
+ Set fundamental = EnumSet.copyOf(semantics);
+ fundamental.retainAll(MODELABLE_TYPES);
+ Color ret = null;
+ if (fundamental.size() == 1) {
+ ret =
+ switch (fundamental.iterator().next()) {
+ case SUBJECT, AGENT -> CONCEPT_COLOR_SUBJECT;
+ case EVENT -> CONCEPT_COLOR_EVENT;
+ case DOMAIN -> CONCEPT_COLOR_DOMAIN;
+ case RELATIONSHIP -> CONCEPT_COLOR_RELATIONSHIP;
+ case PROCESS -> CONCEPT_COLOR_PROCESS;
+ case QUALITY -> CONCEPT_COLOR_QUALITY;
+ case ROLE -> CONCEPT_COLOR_ROLE;
+ case CONFIGURATION -> CONCEPT_COLOR_CONFIGURATION;
+ case TRAIT -> CONCEPT_COLOR_TRAIT;
+ case EXTENT -> CONCEPT_COLOR_EXTENT;
+ default -> null;
+ };
+ }
+ return ret == null ? CONCEPT_COLOR_UNKNOWN : ret;
+ }
}
diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/Urn.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/Urn.java
index 4d2ae7f5f..63af3c26a 100644
--- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/Urn.java
+++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/knowledge/Urn.java
@@ -5,319 +5,300 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
-
import org.integratedmodelling.klab.api.collections.Pair;
import org.integratedmodelling.klab.api.data.Version;
import org.integratedmodelling.klab.api.knowledge.organization.Project;
/**
- * Simple helper to decompose a URN into its constituents and access them with
- * proper semantics.
- *
- * URN is formatted as :::[#params][@version]
- *
- * @author Ferd
+ * Simple helper to decompose a URN into its constituents and access them with proper semantics.
+ *
+ *
URN is formatted as :::[#params][@version]
*
+ * @author Ferd
*/
public class Urn implements Serializable {
-
- final public static String SINGLE_PARAMETER_KEY = "value";
-
- final public static Pattern URN_RESOURCE_PATTERN = Pattern.compile("[A-z]+:[A-z]+:[A-z]+:[A-z]+(#.+)?");
- final public static Pattern URN_KIM_OBJECT_PATTERN = Pattern.compile("[a-z]+(\\.[a-z]+)+");
- final public static Pattern URN_CONCEPT_PATTERN = Pattern.compile("[a-z]+:[A-Z]+");
-
- private String urn;
- private String fullUrn;
- private String[] tokens;
- private Map parameters = new HashMap<>();
-
- public enum Type {
- /**
- * A resource URN
- */
- RESOURCE,
- /**
- * A model, acknowledgement, namespace/scenario, project or define
- */
- KIM_OBJECT,
- /**
- * A concept or observable (no guarantee that it's meaningful)
- */
- OBSERVABLE,
- /**
- * An http-based URL, observable only when it points to a remote observation (no
- * guarantee)
- */
- REMOTE_URL,
- /**
- * Returned by classify() when the passed string cannot be understood as one of
- * the above
- */
- UNKNOWN
- }
-
- /**
- * Pass a valid URN string. For now does no validation.
- *
- * @param urn
- */
- public Urn(String urn) {
- fullUrn = urn;
- if (urn.startsWith(KLAB_URN_PREFIX)) {
- urn = urn.substring(KLAB_URN_PREFIX.length());
- }
- if (urn.contains("#")) {
- String[] uu = urn.split("#");
- urn = uu[0];
- for (String s : uu[1].split("&")) {
- if (s.contains("=")) {
- String[] kv = s.split("=");
- parameters.put(kv[0], kv[1]);
- } else {
- if (parameters.containsKey(SINGLE_PARAMETER_KEY)) {
- parameters.put(SINGLE_PARAMETER_KEY, parameters.get(SINGLE_PARAMETER_KEY) + "," + s);
- } else {
- parameters.put(SINGLE_PARAMETER_KEY, s);
- }
- }
- }
- }
- this.urn = urn;
- this.tokens = urn.split(":");
- }
-
- public Urn(String urn, Map urnParameters) {
- this(urn);
- if (urnParameters != null && !urnParameters.isEmpty()) {
- this.parameters.putAll(urnParameters);
- String s = "";
- for (String key : urnParameters.keySet()) {
- s += (s.isEmpty() ? "" : "&") + ("value".equals(key) ? "" : (key + "="));
- String val = urnParameters.get(key);
- s += val.replace(",", "&");
- }
- this.fullUrn += "#" + s;
- }
- }
-
- /**
- * Node name, mandatory in all URNs. In universal ones it will be "klab". In
- * local ones, it will be "local".
- *
- * @return the node name.
- */
- public String getNodeName() {
- return tokens[0];
- }
-
- /**
- * Whether the URN should be processed by the same engine that generates it.
- *
- * @return true if local
- */
- public boolean isLocal() {
- return getNodeName().equals("local");
- }
-
- /**
- * Return either an empty array for no parameter present, or an array of values
- * with one or more values for the passed parameter set in the url as
- * independent parts. E.g. url#a&b&C would return a, b, C.
- *
- * @param parameter
- * @return
- */
- public String[] getSplitParameter(String parameter) {
- if (parameters.containsKey(parameter)) {
- String ss = parameters.get(parameter);
- if (ss == null) {
- ss = "";
- }
- return ss.split(",");
- }
- return new String[] {};
- }
-
- /**
- * Whether the URN can be processed by any node. In this case, the URN has no
- * attached data and the catalog name is the ID of the adapter that will process
- * it. If we don't have the adapter, we will choose a node among those that do,
- * using the load factor or some other criterion.
- *
- * @return true if universal.
- */
- public boolean isUniversal() {
- return getNodeName().equals("klab");
- }
-
- /**
- * Return the catalog for the resource. In local resources, this is the
- * originator ID. In universal resources, this is the adapter ID. Never null.
- *
- * @return the originator
- */
- public String getCatalog() {
- return tokens[1];
- }
-
- /**
- * Return the namespace of the resource.
- */
- public String getNamespace() {
- return tokens.length > 2 ? tokens[2] : null;
- }
-
- /**
- * Return the resource ID. Never null.
- *
- * @return the resource id.
- */
- public String getResourceId() {
- return tokens.length > 3 ? tokens[3] : null;
- }
-
- /**
- * Return the version, if any.
- *
- * @return
- */
- public Version getVersion() {
- return tokens.length > 4 ? new Version(tokens[4]) : null;
- }
-
- /**
- * Unmodified URN string without parameters
- *
- * @return the unmodified URN.
- */
- public String getUrn() {
- return urn;
- }
-
- @Override
- public String toString() {
- return fullUrn;
- }
-
- public Map getParameters() {
- return parameters;
- }
-
- public static Type classify(String urn) {
-
- if (urn.startsWith("http") && urn.contains("//:")) {
- return Type.REMOTE_URL;
- } else if (URN_RESOURCE_PATTERN.matcher(urn).find()) {
- return Type.RESOURCE;
- } else if (URN_KIM_OBJECT_PATTERN.matcher(urn).find()) {
- return Type.KIM_OBJECT;
- } else if (URN_CONCEPT_PATTERN.matcher(urn).find()) {
- return Type.OBSERVABLE;
- }
-
- return Type.UNKNOWN;
- }
-
- final public static String KLAB_URN_PREFIX = "urn:klab:";
- final public static String LOCAL_URN_PREFIX = "urn:klab:local:";
- final public static String VOID_URN_PREFIX = "urn:klab:void:";
- final public static String LOCAL_FILE_PREFIX = "file:";
-
- public static boolean isLocal(String urn) {
- return urn.startsWith(LOCAL_URN_PREFIX) || urn.startsWith("local:") || urn.startsWith(LOCAL_FILE_PREFIX);
- }
-
- public static boolean isUniversal(String urn) {
- return urn.startsWith(KLAB_URN_PREFIX) || urn.startsWith("klab:");
- }
-
- public String getLocalUrn(String resourceId, Project project, String owner) {
- return "local:" + owner + ":" + project.getUrn() + ":" + resourceId;
- }
-
- /**
- * Create a new local URN with the passed project instead of the original.
- *
- * @param urn
- * @param projectName
- * @return
- */
- public static String changeLocalProject(String urn, String projectName) {
-
- if (!isLocal(urn)) {
- throw new IllegalArgumentException("cannot change project name in non-local URN " + urn);
- }
- int fieldIndex = urn.startsWith(LOCAL_URN_PREFIX) ? 4 : 2;
- String ret = "";
- int i = 0;
- for (String field : urn.split(":")) {
- ret += (ret.isEmpty() ? "" : ":") + (i == fieldIndex ? projectName : field);
- i++;
- }
- return ret;
- }
-
- public static Map parseParameters(String uu) {
- Map ret = new HashMap<>();
- for (String s : uu.split("&")) {
- if (s.contains("=")) {
- String[] kv = s.split("=");
- ret.put(kv[0], kv[1]);
- } else {
- ret.put(Urn.SINGLE_PARAMETER_KEY, s);
- }
- }
- return ret;
- }
-
- /**
- * Split off the fragment and return the parsed parameter map along with the
- * clean URN.
- *
- * @param urn
- * @return
- */
- public static Pair> resolveParameters(String urn) {
- Map parameters = new HashMap<>();
- String clean = urn;
- if (urn.contains("#")) {
- String[] uu = urn.split("#");
- clean = uu[0];
- for (String s : uu[1].split("&")) {
- if (s.contains("=")) {
- String[] kv = s.split("=");
- parameters.put(kv[0], kv[1]);
- } else {
- parameters.put(Urn.SINGLE_PARAMETER_KEY, s);
- }
- }
- }
- return Pair.of(clean, parameters);
- }
-
- public boolean isUrn(String urn) {
- // at least two colons in successive positions with something in the middle
- int ln = urn.indexOf(':');
- return ln > 0 && urn.lastIndexOf(':') > (ln + 1);
- }
-
- public static String applyParameters(String urn, Map urnParameters) {
- String ret = removeParameters(urn);
- if (urnParameters != null && !urnParameters.isEmpty()) {
- boolean first = true;
- for (Entry entry : urnParameters.entrySet()) {
- ret += (first ? "#" : "&") + entry.getKey() + "=" + entry.getValue();
- }
- }
- return ret;
- }
-
- public static String removeParameters(String urn) {
- int pound = urn.indexOf(':');
- return pound > 0 ? urn.substring(0, pound) : urn;
- }
-
-}
\ No newline at end of file
+ public static final String SINGLE_PARAMETER_KEY = "value";
+
+ public static final Pattern URN_RESOURCE_PATTERN =
+ Pattern.compile("[A-z]+:[A-z]+:[A-z]+:[A-z]+(#.+)?");
+ public static final Pattern URN_KIM_OBJECT_PATTERN = Pattern.compile("[a-z]+(\\.[a-z]+)+");
+ public static final Pattern URN_CONCEPT_PATTERN = Pattern.compile("[a-z]+:[A-Z]+");
+
+ private String urn;
+ private String fullUrn;
+ private String[] tokens;
+ private Map parameters = new HashMap<>();
+
+ public enum Type {
+ /** A resource URN */
+ RESOURCE,
+ /** A model, acknowledgement, namespace/scenario, project or define */
+ KIM_OBJECT,
+ /** A concept or observable (no guarantee that it's meaningful) */
+ OBSERVABLE,
+ /** An http-based URL, observable only when it points to a remote observation (no guarantee) */
+ REMOTE_URL,
+ /** Returned by classify() when the passed string cannot be understood as one of the above */
+ UNKNOWN
+ }
+
+ /**
+ * Pass a valid URN string. For now does no validation.
+ *
+ * @param urn
+ */
+ public Urn(String urn) {
+ fullUrn = urn;
+ if (urn.startsWith(KLAB_URN_PREFIX)) {
+ urn = urn.substring(KLAB_URN_PREFIX.length());
+ }
+ if (urn.contains("#")) {
+ String[] uu = urn.split("#");
+ urn = uu[0];
+ for (String s : uu[1].split("&")) {
+ if (s.contains("=")) {
+ String[] kv = s.split("=");
+ parameters.put(kv[0], kv[1]);
+ } else {
+ if (parameters.containsKey(SINGLE_PARAMETER_KEY)) {
+ parameters.put(SINGLE_PARAMETER_KEY, parameters.get(SINGLE_PARAMETER_KEY) + "," + s);
+ } else {
+ parameters.put(SINGLE_PARAMETER_KEY, s);
+ }
+ }
+ }
+ }
+ this.urn = urn;
+ this.tokens = urn.split(":");
+ }
+
+ public Urn(String urn, Map urnParameters) {
+ this(urn);
+ if (urnParameters != null && !urnParameters.isEmpty()) {
+ this.parameters.putAll(urnParameters);
+ String s = "";
+ for (String key : urnParameters.keySet()) {
+ s += (s.isEmpty() ? "" : "&") + ("value".equals(key) ? "" : (key + "="));
+ String val = urnParameters.get(key);
+ s += val.replace(",", "&");
+ }
+ this.fullUrn += "#" + s;
+ }
+ }
+
+ /**
+ * Node name, mandatory in all URNs. In universal ones it will be "klab". In local ones, it will
+ * be "local".
+ *
+ * @return the node name.
+ */
+ public String getNodeName() {
+ return tokens[0];
+ }
+
+ /**
+ * Whether the URN should be processed by the same engine that generates it.
+ *
+ * @return true if local
+ */
+ public boolean isLocal() {
+ return getNodeName().equals("local");
+ }
+
+ /**
+ * Return either an empty array for no parameter present, or an array of values with one or more
+ * values for the passed parameter set in the url as independent parts. E.g. url#a&b&C would
+ * return a, b, C.
+ *
+ * @param parameter
+ * @return
+ */
+ public String[] getSplitParameter(String parameter) {
+ if (parameters.containsKey(parameter)) {
+ String ss = parameters.get(parameter);
+ if (ss == null) {
+ ss = "";
+ }
+ return ss.split(",");
+ }
+ return new String[] {};
+ }
+
+ /**
+ * Whether the URN can be processed by any node. In this case, the URN has no attached data and
+ * the catalog name is the ID of the adapter that will process it. If we don't have the adapter,
+ * we will choose a node among those that do, using the load factor or some other criterion.
+ *
+ * @return true if universal.
+ */
+ public boolean isUniversal() {
+ return getNodeName().equals("klab");
+ }
+
+ /**
+ * Return the catalog for the resource. In local resources, this is the originator ID. In
+ * universal resources, this is the adapter ID. Never null.
+ *
+ * @return the originator
+ */
+ public String getCatalog() {
+ return tokens[1];
+ }
+
+ /** Return the namespace of the resource. */
+ public String getNamespace() {
+ return tokens.length > 2 ? tokens[2] : null;
+ }
+
+ /**
+ * Return the resource ID. Never null.
+ *
+ * @return the resource id.
+ */
+ public String getResourceId() {
+ return tokens.length > 3 ? tokens[3] : null;
+ }
+
+ /**
+ * Return the version, if any.
+ *
+ * @return
+ */
+ public Version getVersion() {
+ return tokens.length > 4 ? new Version(tokens[4]) : null;
+ }
+
+ /**
+ * Unmodified URN string without parameters
+ *
+ * @return the unmodified URN.
+ */
+ public String getUrn() {
+ return urn;
+ }
+
+ @Override
+ public String toString() {
+ return fullUrn;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public static Type classify(String urn) {
+
+ if (urn.startsWith("http") && urn.contains("//:")) {
+ return Type.REMOTE_URL;
+ } else if (URN_RESOURCE_PATTERN.matcher(urn).find()) {
+ return Type.RESOURCE;
+ } else if (URN_KIM_OBJECT_PATTERN.matcher(urn).find()) {
+ return Type.KIM_OBJECT;
+ } else if (URN_CONCEPT_PATTERN.matcher(urn).find()) {
+ return Type.OBSERVABLE;
+ }
+
+ return Type.UNKNOWN;
+ }
+
+ public static final String KLAB_URN_PREFIX = "urn:klab:";
+ public static final String LOCAL_URN_PREFIX = "urn:klab:local:";
+ public static final String VOID_URN_PREFIX = "urn:klab:void:";
+ public static final String LOCAL_FILE_PREFIX = "file:";
+
+ public static boolean isLocal(String urn) {
+ return urn.startsWith(LOCAL_URN_PREFIX)
+ || urn.startsWith("local:")
+ || urn.startsWith(LOCAL_FILE_PREFIX);
+ }
+
+ public static boolean isUniversal(String urn) {
+ return urn.startsWith(KLAB_URN_PREFIX) || urn.startsWith("klab:");
+ }
+
+ public String getLocalUrn(String resourceId, Project project, String owner) {
+ return "local:" + owner + ":" + project.getUrn() + ":" + resourceId;
+ }
+
+ /**
+ * Create a new local URN with the passed project instead of the original.
+ *
+ * @param urn
+ * @param projectName
+ * @return
+ */
+ public static String changeLocalProject(String urn, String projectName) {
+
+ if (!isLocal(urn)) {
+ throw new IllegalArgumentException("cannot change project name in non-local URN " + urn);
+ }
+ int fieldIndex = urn.startsWith(LOCAL_URN_PREFIX) ? 4 : 2;
+ String ret = "";
+ int i = 0;
+ for (String field : urn.split(":")) {
+ ret += (ret.isEmpty() ? "" : ":") + (i == fieldIndex ? projectName : field);
+ i++;
+ }
+ return ret;
+ }
+
+ public static Map parseParameters(String uu) {
+ Map ret = new HashMap<>();
+ for (String s : uu.split("&")) {
+ if (s.contains("=")) {
+ String[] kv = s.split("=");
+ ret.put(kv[0], kv[1]);
+ } else {
+ ret.put(Urn.SINGLE_PARAMETER_KEY, s);
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Split off the fragment and return the parsed parameter map along with the clean URN.
+ *
+ * @param urn
+ * @return
+ */
+ public static Pair> resolveParameters(String urn) {
+ Map parameters = new HashMap<>();
+ String clean = urn;
+ if (urn.contains("#")) {
+ String[] uu = urn.split("#");
+ clean = uu[0];
+ for (String s : uu[1].split("&")) {
+ if (s.contains("=")) {
+ String[] kv = s.split("=");
+ parameters.put(kv[0], kv[1]);
+ } else {
+ parameters.put(Urn.SINGLE_PARAMETER_KEY, s);
+ }
+ }
+ }
+ return Pair.of(clean, parameters);
+ }
+
+ public boolean isUrn(String urn) {
+ // at least two colons in successive positions with something in the middle
+ int ln = urn.indexOf(':');
+ return ln > 0 && urn.lastIndexOf(':') > (ln + 1);
+ }
+
+ public static String applyParameters(String urn, Map urnParameters) {
+ String ret = removeParameters(urn);
+ if (urnParameters != null && !urnParameters.isEmpty()) {
+ boolean first = true;
+ for (Entry entry : urnParameters.entrySet()) {
+ ret += (first ? "#" : "&") + entry.getKey() + "=" + entry.getValue();
+ }
+ }
+ return ret;
+ }
+
+ public static String removeParameters(String urn) {
+ int pound = urn.indexOf(':');
+ return pound > 0 ? urn.substring(0, pound) : urn;
+ }
+}
diff --git a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/view/modeler/Modeler.java b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/view/modeler/Modeler.java
index fc7c2b2a9..e242e94fa 100644
--- a/klab.core.api/src/main/java/org/integratedmodelling/klab/api/view/modeler/Modeler.java
+++ b/klab.core.api/src/main/java/org/integratedmodelling/klab/api/view/modeler/Modeler.java
@@ -3,6 +3,7 @@
import org.integratedmodelling.klab.api.data.RepositoryState;
import org.integratedmodelling.klab.api.knowledge.organization.ProjectStorage;
import org.integratedmodelling.klab.api.scope.ContextScope;
+import org.integratedmodelling.klab.api.scope.Scope;
import org.integratedmodelling.klab.api.scope.SessionScope;
import org.integratedmodelling.klab.api.services.KlabService;
import org.integratedmodelling.klab.api.view.UIController;
@@ -129,6 +130,13 @@ private Option(Class>... payloadClass) {
*/
void setCurrentService(KlabService service);
+ /**
+ * Return the innermost current scope available.
+ *
+ * @return
+ */
+ Scope getCurrentScope();
+
/**
* Make the passed context the current one. The context must belong to the current session or an exception
* will be thrown.
diff --git a/klab.core.common/src/main/java/org/integratedmodelling/common/lang/kim/KimConceptImpl.java b/klab.core.common/src/main/java/org/integratedmodelling/common/lang/kim/KimConceptImpl.java
index 7553ee8aa..eb27ccdda 100644
--- a/klab.core.common/src/main/java/org/integratedmodelling/common/lang/kim/KimConceptImpl.java
+++ b/klab.core.common/src/main/java/org/integratedmodelling/common/lang/kim/KimConceptImpl.java
@@ -12,775 +12,781 @@
public class KimConceptImpl extends KimStatementImpl implements KimConcept {
- @Serial
- private static final long serialVersionUID = 8531431719010407385L;
-
- private SemanticRole semanticRole;
- private String name;
- private Set type = EnumSet.noneOf(SemanticType.class);
- private KimConcept observable;
- private KimConcept parent;
- private KimConcept inherent;
- private KimConcept goal;
- private KimConcept causant;
- private KimConcept caused;
- private KimConcept compresent;
- private KimConcept comparisonConcept;
- private String authorityTerm;
- private String authority;
- private UnarySemanticOperator semanticModifier;
- private KimConcept relationshipSource;
- private KimConcept relationshipTarget;
- private List traits = new ArrayList<>();
- private List roles = new ArrayList<>();
- private boolean negated;
- private String urn;
- private List operands = new ArrayList<>();
- private Expression expressionType;
- private SemanticType fundamentalType;
- private KimConcept cooccurrent;
- private KimConcept adjacent;
- private String codeName;
- private KimConcept temporalInherent;
- private boolean collective;
- private boolean pattern;
- private Set patternVariables = new HashSet<>();
-
- public Set getArgumentType() {
- return argumentType;
- }
-
- public void setArgumentType(Set argumentType) {
- this.argumentType = argumentType;
+ @Serial private static final long serialVersionUID = 8531431719010407385L;
+
+ private SemanticRole semanticRole;
+ private String name;
+ private Set type = EnumSet.noneOf(SemanticType.class);
+ private KimConcept observable;
+ private KimConcept parent;
+ private KimConcept inherent;
+ private KimConcept goal;
+ private KimConcept causant;
+ private KimConcept caused;
+ private KimConcept compresent;
+ private KimConcept comparisonConcept;
+ private String authorityTerm;
+ private String authority;
+ private UnarySemanticOperator semanticModifier;
+ private KimConcept relationshipSource;
+ private KimConcept relationshipTarget;
+ private List traits = new ArrayList<>();
+ private List roles = new ArrayList<>();
+ private boolean negated;
+ private String urn;
+ private List operands = new ArrayList<>();
+ private Expression expressionType;
+ private SemanticType fundamentalType;
+ private KimConcept cooccurrent;
+ private KimConcept adjacent;
+ private String codeName;
+ private KimConcept temporalInherent;
+ private boolean collective;
+ private boolean pattern;
+ private Set patternVariables = new HashSet<>();
+
+ public Set getArgumentType() {
+ return argumentType;
+ }
+
+ public void setArgumentType(Set argumentType) {
+ this.argumentType = argumentType;
+ }
+
+ public KimConceptImpl() {}
+
+ private transient Set argumentType = EnumSet.noneOf(SemanticType.class);
+
+ private KimConceptImpl(KimConceptImpl other) {
+ super(other);
+ this.semanticRole = other.semanticRole;
+ this.name = other.name;
+ this.type = EnumSet.copyOf(other.type);
+ this.observable = other.observable;
+ this.parent = other.parent;
+ this.inherent = other.inherent;
+ this.goal = other.goal;
+ this.causant = other.causant;
+ this.caused = other.caused;
+ this.compresent = other.compresent;
+ this.comparisonConcept = other.comparisonConcept;
+ this.authorityTerm = other.authority;
+ this.authority = other.authority;
+ this.semanticModifier = other.semanticModifier;
+ this.collective = other.collective;
+ this.relationshipSource = other.relationshipSource;
+ this.relationshipTarget = other.relationshipTarget;
+ this.traits.addAll(other.traits);
+ this.roles.addAll(other.roles);
+ this.negated = other.negated;
+ this.urn = other.urn;
+ this.operands.addAll(other.operands);
+ this.expressionType = other.expressionType;
+ this.fundamentalType = other.fundamentalType;
+ this.cooccurrent = other.cooccurrent;
+ this.adjacent = other.adjacent;
+ this.codeName = other.codeName;
+ this.temporalInherent = other.temporalInherent;
+ this.argumentType = EnumSet.copyOf(other.argumentType);
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public Set getType() {
+ return this.type;
+ }
+
+ @Override
+ public KimConcept getObservable() {
+ return this.observable;
+ }
+
+ @Override
+ public KimConcept getInherent() {
+ return this.inherent;
+ }
+
+ @Override
+ public KimConcept getGoal() {
+ return this.goal;
+ }
+
+ @Override
+ public KimConcept getCausant() {
+ return this.causant;
+ }
+
+ @Override
+ public KimConcept getCaused() {
+ return this.caused;
+ }
+
+ @Override
+ public KimConcept getCompresent() {
+ return this.compresent;
+ }
+
+ @Override
+ public KimConcept getComparisonConcept() {
+ return this.comparisonConcept;
+ }
+
+ @Override
+ public String getAuthorityTerm() {
+ return this.authorityTerm;
+ }
+
+ @Override
+ public String getAuthority() {
+ return this.authority;
+ }
+
+ @Override
+ public UnarySemanticOperator getSemanticModifier() {
+ return this.semanticModifier;
+ }
+
+ @Override
+ public KimConcept getRelationshipSource() {
+ return this.relationshipSource;
+ }
+
+ @Override
+ public KimConcept getRelationshipTarget() {
+ return this.relationshipTarget;
+ }
+
+ @Override
+ public List getTraits() {
+ return this.traits;
+ }
+
+ @Override
+ public List getRoles() {
+ return this.roles;
+ }
+
+ @Override
+ public boolean isNegated() {
+ return this.negated;
+ }
+
+ @Override
+ public String getUrn() {
+ return this.urn;
+ }
+
+ @Override
+ public boolean is(SemanticType type) {
+ return this.type.contains(type);
+ }
+
+ @Override
+ public List getOperands() {
+ return this.operands;
+ }
+
+ @Override
+ public Expression getExpressionType() {
+ return this.expressionType;
+ }
+
+ @Override
+ public SemanticType getFundamentalType() {
+ return this.fundamentalType;
+ }
+
+ @Override
+ public KimConcept getCooccurrent() {
+ return this.cooccurrent;
+ }
+
+ @Override
+ public KimConcept getAdjacent() {
+ return this.adjacent;
+ }
+
+ @Override
+ public String getCodeName() {
+ return this.codeName;
+ }
+
+ @Override
+ public SemanticRole getSemanticRole() {
+ return this.semanticRole;
+ }
+
+ @Override
+ public KimConcept getTemporalInherent() {
+ return this.temporalInherent;
+ }
+
+ public void setSemanticRole(SemanticRole semanticRole) {
+ this.semanticRole = semanticRole;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setType(Set type) {
+ this.type = type;
+ }
+
+ public void setObservable(KimConcept observable) {
+ this.observable = observable;
+ }
+
+ public void setInherent(KimConcept inherent) {
+ this.inherent = inherent;
+ }
+
+ public void setGoal(KimConcept motivation) {
+ this.goal = motivation;
+ }
+
+ public void setCausant(KimConcept causant) {
+ this.causant = causant;
+ }
+
+ public void setCaused(KimConcept caused) {
+ this.caused = caused;
+ }
+
+ public void setCompresent(KimConcept compresent) {
+ this.compresent = compresent;
+ }
+
+ public void setComparisonConcept(KimConcept comparisonConcept) {
+ this.comparisonConcept = comparisonConcept;
+ }
+
+ public void setAuthorityTerm(String authorityTerm) {
+ this.authorityTerm = authorityTerm;
+ }
+
+ public void setAuthority(String authority) {
+ this.authority = authority;
+ }
+
+ public void setSemanticModifier(UnarySemanticOperator semanticModifier) {
+ this.semanticModifier = semanticModifier;
+ }
+
+ public void setRelationshipSource(KimConcept relationshipSource) {
+ this.relationshipSource = relationshipSource;
+ }
+
+ public void setRelationshipTarget(KimConcept relationshipTarget) {
+ this.relationshipTarget = relationshipTarget;
+ }
+
+ public void setTraits(List traits) {
+ this.traits = traits;
+ }
+
+ public void setRoles(List roles) {
+ this.roles = roles;
+ }
+
+ // public void setTemplate(boolean template) {
+ // this.template = template;
+ // }
+
+ public void setNegated(boolean negated) {
+ this.negated = negated;
+ }
+
+ public void setUrn(String urn) {
+ this.urn = urn;
+ ;
+ }
+
+ public void setOperands(List operands) {
+ this.operands = operands;
+ }
+
+ public void setExpressionType(Expression expressionType) {
+ this.expressionType = expressionType;
+ }
+
+ public void setFundamentalType(SemanticType fundamentalType) {
+ this.fundamentalType = fundamentalType;
+ }
+
+ public void setCooccurrent(KimConcept cooccurrent) {
+ this.cooccurrent = cooccurrent;
+ }
+
+ public void setAdjacent(KimConcept adjacent) {
+ this.adjacent = adjacent;
+ }
+
+ public void setCodeName(String codeName) {
+ this.codeName = codeName;
+ }
+
+ public void setTemporalInherent(KimConcept temporalInherent) {
+ this.temporalInherent = temporalInherent;
+ }
+
+ @Override
+ public KimConcept getParent() {
+ return parent;
+ }
+
+ public void setParent(KimConcept parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public String toString() {
+ return this.urn;
+ }
+
+ /*
+ * modification methods
+ */
+
+ public KimConcept removeOperator() {
+ KimConceptImpl ret = new KimConceptImpl(this);
+ if (this.semanticModifier != null) {
+ ret.semanticModifier = null;
+ ret.comparisonConcept = null;
+ ret.type = this.argumentType;
+ ret.urn = ret.computeUrn();
+ }
+ return ret;
+ }
+
+ public KimConcept removeComponents(SemanticRole... roles) {
+
+ KimConceptImpl ret = new KimConceptImpl(this);
+
+ for (SemanticRole role : roles) {
+
+ switch (role) {
+ case ADJACENT:
+ ret.adjacent = null;
+ break;
+ case CAUSANT:
+ ret.causant = null;
+ break;
+ case CAUSED:
+ ret.caused = null;
+ break;
+ case COMPRESENT:
+ ret.compresent = null;
+ break;
+ // case CONTEXT:
+ // ret.context = null;
+ // break;
+ case COOCCURRENT:
+ ret.cooccurrent = null;
+ break;
+ case GOAL:
+ ret.goal = null;
+ break;
+ case INHERENT:
+ ret.inherent = null;
+ break;
+ case ROLE:
+ ret.roles.clear();
+ break;
+ case TRAIT:
+ ret.traits.clear();
+ break;
+ case TEMPORAL_INHERENT:
+ ret.temporalInherent = null;
+ break;
+ case UNARY_OPERATOR:
+ ((KimConceptImpl) ret.observable).semanticModifier = null;
+ break;
+ default:
+ break;
+ }
+ }
+
+ this.urn = ret.urn = computeUrn();
+
+ return ret;
+ }
+
+ public KimConcept removeComponents(List declarations, List roles) {
+
+ KimConceptImpl ret = new KimConceptImpl(this);
+
+ for (int i = 0; i < declarations.size(); i++) {
+
+ String declaration = declarations.get(i);
+ SemanticRole role = roles.get(i);
+
+ switch (role) {
+ case ADJACENT:
+ ret.adjacent = null;
+ break;
+ case CAUSANT:
+ ret.causant = null;
+ break;
+ case CAUSED:
+ ret.caused = null;
+ break;
+ case COMPRESENT:
+ ret.compresent = null;
+ break;
+ // case CONTEXT:
+ // ret.context = null;
+ // break;
+ case COOCCURRENT:
+ ret.cooccurrent = null;
+ break;
+ case GOAL:
+ ret.goal = null;
+ break;
+ case INHERENT:
+ ret.inherent = null;
+ break;
+ case TEMPORAL_INHERENT:
+ ret.temporalInherent = null;
+ break;
+ case ROLE:
+ ret.roles = copyWithout(ret.roles, declaration);
+ break;
+ case TRAIT:
+ ret.traits = copyWithout(ret.traits, declaration);
+ break;
+ default:
+ break;
+ }
+ }
+
+ this.urn = computeUrn();
+
+ return ret;
+ }
+
+ private static List copyWithout(List concepts, String declaration) {
+ List ret = new ArrayList<>();
+ for (KimConcept c : concepts) {
+ if (!c.toString().equals(declaration)) {
+ ret.add(c);
+ }
+ }
+ return ret;
+ }
+
+ /** Create a text declaration that can be parsed back into a concept. */
+ public String computeUrn() {
+
+ String ret = isCollective() ? "each" : "";
+ boolean complex = false;
+
+ if (type.contains(SemanticType.NOTHING)) {
+ return "owl:Nothing";
+ }
+
+ if (semanticModifier != null) {
+ ret += (ret.isEmpty() ? "" : " ") + semanticModifier.declaration[0];
+ complex = true;
+ }
+
+ if (negated) {
+ ret += (ret.isEmpty() ? "" : " ") + "not";
+ complex = true;
}
- public KimConceptImpl() {
- }
-
- transient private Set argumentType = EnumSet.noneOf(SemanticType.class);
-
- private KimConceptImpl(KimConceptImpl other) {
- super(other);
- this.semanticRole = other.semanticRole;
- this.name = other.name;
- this.type = EnumSet.copyOf(other.type);
- this.observable = other.observable;
- this.parent = other.parent;
- this.inherent = other.inherent;
- this.goal = other.goal;
- this.causant = other.causant;
- this.caused = other.caused;
- this.compresent = other.compresent;
- this.comparisonConcept = other.comparisonConcept;
- this.authorityTerm = other.authority;
- this.authority = other.authority;
- this.semanticModifier = other.semanticModifier;
- this.collective = other.collective;
- this.relationshipSource = other.relationshipSource;
- this.relationshipTarget = other.relationshipTarget;
- this.traits.addAll(other.traits);
- this.roles.addAll(other.roles);
- this.negated = other.negated;
- this.urn = other.urn;
- this.operands.addAll(other.operands);
- this.expressionType = other.expressionType;
- this.fundamentalType = other.fundamentalType;
- this.cooccurrent = other.cooccurrent;
- this.adjacent = other.adjacent;
- this.codeName = other.codeName;
- this.temporalInherent = other.temporalInherent;
- this.argumentType = EnumSet.copyOf(other.argumentType);
- }
-
- @Override
- public String getName() {
- return this.name;
- }
-
- @Override
- public Set getType() {
- return this.type;
- }
-
- @Override
- public KimConcept getObservable() {
- return this.observable;
- }
-
- @Override
- public KimConcept getInherent() {
- return this.inherent;
- }
-
- @Override
- public KimConcept getGoal() {
- return this.goal;
- }
-
- @Override
- public KimConcept getCausant() {
- return this.causant;
- }
-
- @Override
- public KimConcept getCaused() {
- return this.caused;
- }
-
- @Override
- public KimConcept getCompresent() {
- return this.compresent;
- }
-
- @Override
- public KimConcept getComparisonConcept() {
- return this.comparisonConcept;
- }
-
- @Override
- public String getAuthorityTerm() {
- return this.authorityTerm;
- }
-
- @Override
- public String getAuthority() {
- return this.authority;
- }
-
- @Override
- public UnarySemanticOperator getSemanticModifier() {
- return this.semanticModifier;
- }
-
- @Override
- public KimConcept getRelationshipSource() {
- return this.relationshipSource;
- }
-
- @Override
- public KimConcept getRelationshipTarget() {
- return this.relationshipTarget;
- }
-
- @Override
- public List getTraits() {
- return this.traits;
- }
-
- @Override
- public List getRoles() {
- return this.roles;
- }
-
- @Override
- public boolean isNegated() {
- return this.negated;
- }
-
- @Override
- public String getUrn() {
- return this.urn;
- }
-
- @Override
- public boolean is(SemanticType type) {
- return this.type.contains(type);
- }
-
- @Override
- public List getOperands() {
- return this.operands;
- }
-
- @Override
- public Expression getExpressionType() {
- return this.expressionType;
- }
-
- @Override
- public SemanticType getFundamentalType() {
- return this.fundamentalType;
- }
-
- @Override
- public KimConcept getCooccurrent() {
- return this.cooccurrent;
- }
+ StringBuilder concepts = new StringBuilder();
+ boolean ccomplex = false;
- @Override
- public KimConcept getAdjacent() {
- return this.adjacent;
+ for (KimConcept trait : traits) {
+ concepts
+ .append((concepts.isEmpty()) ? "" : " ")
+ .append(parenthesize(((KimConceptImpl) trait).computeUrn()));
+ ccomplex = true;
}
- @Override
- public String getCodeName() {
- return this.codeName;
+ for (KimConcept role : roles) {
+ concepts
+ .append((concepts.isEmpty()) ? "" : " ")
+ .append(parenthesize(((KimConceptImpl) role).computeUrn()));
+ ccomplex = true;
}
- @Override
- public SemanticRole getSemanticRole() {
- return this.semanticRole;
- }
+ // for (KimConcept conc : unclassified) {
+ // concepts += (concepts.isEmpty() ? "" : " ") + conc;
+ // ccomplex = true;
+ // }
+
+ concepts
+ .append((concepts.isEmpty()) ? "" : " ")
+ .append(name == null ? ((KimConceptImpl) observable).computeUrn() : name);
+ var needsParentheses = ccomplex && !ret.equals("each");
+ ret +=
+ (ret.isEmpty() ? "" : " ")
+ + (needsParentheses ? "(" : "")
+ + concepts
+ + (needsParentheses ? ")" : "");
- @Override
- public KimConcept getTemporalInherent() {
- return this.temporalInherent;
+ if (comparisonConcept != null) {
+ ret +=
+ " "
+ + semanticModifier.declaration[1]
+ + " "
+ + ((KimConceptImpl) comparisonConcept).computeUrn();
+ complex = true;
}
- public void setSemanticRole(SemanticRole semanticRole) {
- this.semanticRole = semanticRole;
- }
+ // if (authority != null) {
+ // ret += " identified as " + stringify(authorityTerm) + " by " + authority;
+ // complex = true;
+ // }
- public void setName(String name) {
- this.name = name;
+ if (inherent != null) {
+ ret += " of " + ((KimConceptImpl) inherent).computeUrn();
+ complex = true;
}
- public void setType(Set type) {
- this.type = type;
- }
+ // if (context != null) {
+ // ret += " within " + ((KimConceptImpl) context).computeUrn();
+ // complex = true;
+ // }
- public void setObservable(KimConcept observable) {
- this.observable = observable;
+ if (causant != null) {
+ ret += " caused by " + ((KimConceptImpl) causant).computeUrn();
+ complex = true;
}
- public void setInherent(KimConcept inherent) {
- this.inherent = inherent;
+ if (caused != null) {
+ ret += " causing " + ((KimConceptImpl) caused).computeUrn();
+ complex = true;
}
- public void setGoal(KimConcept motivation) {
- this.goal = motivation;
+ if (compresent != null) {
+ ret += " with " + ((KimConceptImpl) compresent).computeUrn();
+ complex = true;
}
- public void setCausant(KimConcept causant) {
- this.causant = causant;
+ if (cooccurrent != null) {
+ ret += " during " + ((KimConceptImpl) cooccurrent).computeUrn();
+ complex = true;
}
- public void setCaused(KimConcept caused) {
- this.caused = caused;
+ if (temporalInherent != null) {
+ ret += " during each " + ((KimConceptImpl) temporalInherent).computeUrn();
+ complex = true;
}
- public void setCompresent(KimConcept compresent) {
- this.compresent = compresent;
+ if (adjacent != null) {
+ ret += " adjacent to " + ((KimConceptImpl) adjacent).computeUrn();
+ complex = true;
}
- public void setComparisonConcept(KimConcept comparisonConcept) {
- this.comparisonConcept = comparisonConcept;
+ if (goal != null) {
+ ret += " for " + ((KimConceptImpl) goal).computeUrn();
+ complex = true;
}
- public void setAuthorityTerm(String authorityTerm) {
- this.authorityTerm = authorityTerm;
+ if (relationshipSource != null) {
+ ret += " linking " + ((KimConceptImpl) relationshipSource).computeUrn();
+ if (relationshipTarget != null) {
+ ret += " to " + ((KimConceptImpl) relationshipSource).computeUrn();
+ }
+ complex = true;
}
- public void setAuthority(String authority) {
- this.authority = authority;
- }
+ boolean expression = false;
+ for (KimConcept operand : operands) {
+ ret += " " + (expressionType == Expression.INTERSECTION ? "and" : "or") + " " + operand;
+ complex = true;
+ expression = true;
+ }
+
+ return (expression /* ccomplex || complex */) ? parenthesize(ret) : ret;
+ }
- public void setSemanticModifier(UnarySemanticOperator semanticModifier) {
- this.semanticModifier = semanticModifier;
- }
+ /**
+ * Add parentheses around a declaration unless it is already enclosed in parentheses or it is a
+ * single concept.
+ *
+ * @param ret
+ * @return
+ */
+ private static String parenthesize(String ret) {
+ ret = ret.trim();
+ boolean enclosed = ret.startsWith("(") && ret.endsWith(")");
+ boolean trivial = !ret.trim().contains(" ");
+ return (enclosed || trivial) ? ret : ("(" + ret + ")");
+ }
- public void setRelationshipSource(KimConcept relationshipSource) {
- this.relationshipSource = relationshipSource;
- }
+ private String stringify(String term) {
- public void setRelationshipTarget(KimConcept relationshipTarget) {
- this.relationshipTarget = relationshipTarget;
+ if (term.startsWith("\"")) {
+ return term;
}
- public void setTraits(List traits) {
- this.traits = traits;
- }
+ boolean ws = false;
- public void setRoles(List roles) {
- this.roles = roles;
+ // stringify anything that's not a lowercase ID
+ for (int i = 0; i < term.length(); i++) {
+ if (Character.isWhitespace(term.charAt(i))
+ || !(Character.isLetter(term.charAt(i))
+ || Character.isDigit(term.charAt(i))
+ || term.charAt(i) == '_')) {
+ ws = true;
+ break;
+ }
}
- // public void setTemplate(boolean template) {
- // this.template = template;
- // }
+ // TODO should escape any internal double quotes, unlikely
+ return ws ? ("\"" + term + "\"") : term;
+ }
- public void setNegated(boolean negated) {
- this.negated = negated;
- }
+ @Override
+ public boolean isCollective() {
+ return collective;
+ }
- public void setUrn(String urn) {
- this.urn = urn;
- ;
- }
+ public void setCollective(boolean collective) {
+ this.collective = collective;
+ }
- public void setOperands(List operands) {
- this.operands = operands;
- }
+ @Override
+ public int hashCode() {
+ return Objects.hash(urn);
+ }
- public void setExpressionType(Expression expressionType) {
- this.expressionType = expressionType;
- }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ KimConceptImpl other = (KimConceptImpl) obj;
+ return Objects.equals(urn, other.urn);
+ }
- public void setFundamentalType(SemanticType fundamentalType) {
- this.fundamentalType = fundamentalType;
- }
+ /**
+ * Call after making modifications to finalize the concept and update the URN
+ *
+ *
TODO check abstract state as well
+ */
+ public void finalizeDefinition() {
+ this.urn = computeUrn();
+ }
- public void setCooccurrent(KimConcept cooccurrent) {
- this.cooccurrent = cooccurrent;
- }
+ public static KimConcept nothing() {
+ var ret = new KimConceptImpl();
+ ret.setName("Nothing");
+ ret.setNamespace("klab");
+ ret.setType(EnumSet.of(SemanticType.NOTHING));
+ return ret;
+ }
- public void setAdjacent(KimConcept adjacent) {
- this.adjacent = adjacent;
- }
+ @Override
+ public boolean isPattern() {
+ return pattern;
+ }
- public void setCodeName(String codeName) {
- this.codeName = codeName;
- }
+ public void setPattern(boolean pattern) {
+ this.pattern = pattern;
+ }
- public void setTemporalInherent(KimConcept temporalInherent) {
- this.temporalInherent = temporalInherent;
- }
+ @Override
+ public Set getPatternVariables() {
+ return patternVariables;
+ }
- @Override
- public KimConcept getParent() {
- return parent;
- }
+ public void setPatternVariables(Set patternVariables) {
+ this.patternVariables = patternVariables;
+ }
- public void setParent(KimConcept parent) {
- this.parent = parent;
- }
+ @Override
+ public void visit(Visitor visitor) {
- @Override
- public String toString() {
- return this.urn;
+ if (observable != null) {
+ observable.visit(visitor);
}
- /*
- * modification methods
- */
-
- public KimConcept removeOperator() {
- KimConceptImpl ret = new KimConceptImpl(this);
- if (this.semanticModifier != null) {
- ret.semanticModifier = null;
- ret.comparisonConcept = null;
- ret.type = this.argumentType;
- ret.urn = ret.computeUrn();
- }
- return ret;
+ if (authority != null) {
+ // visitor.visitAuthority(authority, authorityTerm);
}
- public KimConcept removeComponents(SemanticRole... roles) {
-
- KimConceptImpl ret = new KimConceptImpl(this);
-
- for (SemanticRole role : roles) {
-
- switch (role) {
- case ADJACENT:
- ret.adjacent = null;
- break;
- case CAUSANT:
- ret.causant = null;
- break;
- case CAUSED:
- ret.caused = null;
- break;
- case COMPRESENT:
- ret.compresent = null;
- break;
- // case CONTEXT:
- // ret.context = null;
- // break;
- case COOCCURRENT:
- ret.cooccurrent = null;
- break;
- case GOAL:
- ret.goal = null;
- break;
- case INHERENT:
- ret.inherent = null;
- break;
- case ROLE:
- ret.roles.clear();
- break;
- case TRAIT:
- ret.traits.clear();
- break;
- case TEMPORAL_INHERENT:
- ret.temporalInherent = null;
- break;
- case UNARY_OPERATOR:
- ((KimConceptImpl) ret.observable).semanticModifier = null;
- break;
- default:
- break;
- }
- }
-
- this.urn = ret.urn = computeUrn();
-
- return ret;
- }
-
- public KimConcept removeComponents(List declarations, List roles) {
-
- KimConceptImpl ret = new KimConceptImpl(this);
-
- for (int i = 0; i < declarations.size(); i++) {
-
- String declaration = declarations.get(i);
- SemanticRole role = roles.get(i);
-
- switch (role) {
- case ADJACENT:
- ret.adjacent = null;
- break;
- case CAUSANT:
- ret.causant = null;
- break;
- case CAUSED:
- ret.caused = null;
- break;
- case COMPRESENT:
- ret.compresent = null;
- break;
- // case CONTEXT:
- // ret.context = null;
- // break;
- case COOCCURRENT:
- ret.cooccurrent = null;
- break;
- case GOAL:
- ret.goal = null;
- break;
- case INHERENT:
- ret.inherent = null;
- break;
- case TEMPORAL_INHERENT:
- ret.temporalInherent = null;
- break;
- case ROLE:
- ret.roles = copyWithout(ret.roles, declaration);
- break;
- case TRAIT:
- ret.traits = copyWithout(ret.traits, declaration);
- break;
- default:
- break;
- }
- }
-
- this.urn = computeUrn();
-
- return ret;
- }
-
- private static List copyWithout(List concepts, String declaration) {
- List ret = new ArrayList<>();
- for (KimConcept c : concepts) {
- if (!c.toString().equals(declaration)) {
- ret.add(c);
- }
- }
- return ret;
- }
-
- /**
- * Create a text declaration that can be parsed back into a concept.
- */
- public String computeUrn() {
-
- String ret = isCollective() ? "each" : "";
- boolean complex = false;
-
- if (type.contains(SemanticType.NOTHING)) {
- return "owl:Nothing";
- }
-
- if (semanticModifier != null) {
- ret += (ret.isEmpty() ? "" : " ") + semanticModifier.declaration[0];
- complex = true;
- }
-
- if (negated) {
- ret += (ret.isEmpty() ? "" : " ") + "not";
- complex = true;
- }
-
- StringBuilder concepts = new StringBuilder();
- boolean ccomplex = false;
-
- for (KimConcept trait : traits) {
- concepts.append((concepts.isEmpty()) ? "" : " ").append(
- parenthesize(((KimConceptImpl) trait).computeUrn()));
- ccomplex = true;
- }
-
- for (KimConcept role : roles) {
- concepts.append((concepts.isEmpty()) ? "" : " ").append(
- parenthesize(((KimConceptImpl) role).computeUrn()));
- ccomplex = true;
- }
-
- // for (KimConcept conc : unclassified) {
- // concepts += (concepts.isEmpty() ? "" : " ") + conc;
- // ccomplex = true;
- // }
-
- concepts.append((concepts.isEmpty()) ? "" : " ").append(
- name == null ? ((KimConceptImpl) observable).computeUrn() : name);
- var needsParentheses = ccomplex && !ret.equals("each");
- ret += (ret.isEmpty() ? "" : " ") + (needsParentheses ? "(" : "") + concepts + (needsParentheses ?
- ")" : "");
-
- if (comparisonConcept != null) {
- ret += " " + semanticModifier.declaration[1] + " " + ((KimConceptImpl) comparisonConcept).computeUrn();
- complex = true;
- }
-
- // if (authority != null) {
- // ret += " identified as " + stringify(authorityTerm) + " by " + authority;
- // complex = true;
- // }
-
- if (inherent != null) {
- ret += " of " + ((KimConceptImpl) inherent).computeUrn();
- complex = true;
- }
-
- // if (context != null) {
- // ret += " within " + ((KimConceptImpl) context).computeUrn();
- // complex = true;
- // }
-
- if (causant != null) {
- ret += " caused by " + ((KimConceptImpl) causant).computeUrn();
- complex = true;
- }
-
- if (caused != null) {
- ret += " causing " + ((KimConceptImpl) caused).computeUrn();
- complex = true;
- }
-
- if (compresent != null) {
- ret += " with " + ((KimConceptImpl) compresent).computeUrn();
- complex = true;
- }
-
- if (cooccurrent != null) {
- ret += " during " + ((KimConceptImpl) cooccurrent).computeUrn();
- complex = true;
- }
-
- if (temporalInherent != null) {
- ret += " during each " + ((KimConceptImpl) temporalInherent).computeUrn();
- complex = true;
- }
-
- if (adjacent != null) {
- ret += " adjacent to " + ((KimConceptImpl) adjacent).computeUrn();
- complex = true;
- }
-
- if (goal != null) {
- ret += " for " + ((KimConceptImpl) goal).computeUrn();
- complex = true;
- }
-
- if (relationshipSource != null) {
- ret += " linking " + ((KimConceptImpl) relationshipSource).computeUrn();
- if (relationshipTarget != null) {
- ret += " to " + ((KimConceptImpl) relationshipSource).computeUrn();
- }
- complex = true;
- }
-
- boolean expression = false;
- for (KimConcept operand : operands) {
- ret += " " + (expressionType == Expression.INTERSECTION ? "and" : "or") + " " + operand;
- complex = true;
- expression = true;
- }
-
- return (expression /* ccomplex || complex */) ? parenthesize(ret) : ret;
+ for (KimConcept trait : traits) {
+ trait.visit(visitor);
}
- /**
- * Add parentheses around a declaration unless it is already enclosed in parentheses or it is a single
- * concept.
- *
- * @param ret
- * @return
- */
- private static String parenthesize(String ret) {
- ret = ret.trim();
- boolean enclosed = ret.startsWith("(") && ret.endsWith(")");
- boolean trivial = !ret.trim().contains(" ");
- return (enclosed || trivial) ? ret : ("(" + ret + ")");
+ for (KimConcept role : roles) {
+ role.visit(visitor);
}
- private String stringify(String term) {
-
- if (term.startsWith("\"")) {
- return term;
- }
-
- boolean ws = false;
-
- // stringify anything that's not a lowercase ID
- for (int i = 0; i < term.length(); i++) {
- if (Character.isWhitespace(term.charAt(i)) || !(Character.isLetter(
- term.charAt(i)) || Character.isDigit(term.charAt(i)) || term.charAt(i) == '_')) {
- ws = true;
- break;
- }
- }
-
- // TODO should escape any internal double quotes, unlikely
- return ws ? ("\"" + term + "\"") : term;
- }
-
- @Override
- public boolean isCollective() {
- return collective;
+ if (inherent != null) {
+ inherent.visit(visitor);
}
- public void setCollective(boolean collective) {
- this.collective = collective;
+ if (causant != null) {
+ causant.visit(visitor);
}
- @Override
- public int hashCode() {
- return Objects.hash(urn);
+ if (caused != null) {
+ caused.visit(visitor);
}
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- KimConceptImpl other = (KimConceptImpl) obj;
- return Objects.equals(urn, other.urn);
+ if (compresent != null) {
+ compresent.visit(visitor);
}
- /**
- * Call after making modifications to finalize the concept and update the URN
- *
- * TODO check abstract state as well
- */
- public void finalizeDefinition() {
- this.urn = computeUrn();
+ if (cooccurrent != null) {
+ cooccurrent.visit(visitor);
}
-
- public static KimConcept nothing() {
- var ret = new KimConceptImpl();
- ret.setName("Nothing");
- ret.setNamespace("klab");
- ret.setType(EnumSet.of(SemanticType.NOTHING));
- return ret;
+ if (adjacent != null) {
+ adjacent.visit(visitor);
}
- @Override
- public boolean isPattern() {
- return pattern;
+ if (temporalInherent != null) {
+ temporalInherent.visit(visitor);
}
- public void setPattern(boolean pattern) {
- this.pattern = pattern;
+ if (goal != null) {
+ goal.visit(visitor);
}
- @Override
- public Set getPatternVariables() {
- return patternVariables;
+ if (relationshipSource != null) {
+ relationshipSource.visit(visitor);
}
- public void setPatternVariables(Set patternVariables) {
- this.patternVariables = patternVariables;
+ if (relationshipTarget != null) {
+ relationshipTarget.visit(visitor);
}
- @Override
- public void visit(Visitor visitor) {
-
- if (observable != null) {
- observable.visit(visitor);
- }
-
- if (authority != null) {
- // visitor.visitAuthority(authority, authorityTerm);
- }
-
- for (KimConcept trait : traits) {
- trait.visit(visitor);
- }
-
- for (KimConcept role : roles) {
- role.visit(visitor);
- }
-
- if (inherent != null) {
- inherent.visit(visitor);
- }
-
- if (causant != null) {
- causant.visit(visitor);
- }
-
- if (caused != null) {
- caused.visit(visitor);
- }
-
- if (compresent != null) {
- compresent.visit(visitor);
- }
-
- if (cooccurrent != null) {
- cooccurrent.visit(visitor);
- }
-
- if (adjacent != null) {
- adjacent.visit(visitor);
- }
-
- if (temporalInherent != null) {
- temporalInherent.visit(visitor);
- }
-
- if (goal != null) {
- goal.visit(visitor);
- }
-
- if (relationshipSource != null) {
- relationshipSource.visit(visitor);
- }
-
- if (relationshipTarget != null) {
- relationshipTarget.visit(visitor);
- }
-
- if (comparisonConcept != null) {
- comparisonConcept.visit(visitor);
- }
-
+ if (comparisonConcept != null) {
+ comparisonConcept.visit(visitor);
}
+ }
- @Override
- public Triple semanticOperation() {
- if (semanticModifier != null) {
- return Triple.of(semanticModifier, observable, comparisonConcept);
- }
- return null;
+ @Override
+ public Triple semanticOperation() {
+ if (semanticModifier != null) {
+ return Triple.of(semanticModifier, observable, comparisonConcept);
}
+ return null;
+ }
- @Override
- public KimConcept semanticClause(SemanticClause semanticClause) {
- return switch (semanticClause) {
- case OF -> inherent;
- case FOR -> goal;
- case WITH -> compresent;
- case CAUSED_BY -> causant;
- case ADJACENT_TO -> adjacent;
- case CAUSING -> caused;
- case DURING -> temporalInherent;
- case LINKING -> relationshipSource;
- case TO -> relationshipTarget;
- };
- }
+ @Override
+ public KimConcept semanticClause(SemanticClause semanticClause) {
+ return switch (semanticClause) {
+ case OF -> inherent;
+ case FOR -> goal;
+ case WITH -> compresent;
+ case CAUSED_BY -> causant;
+ case ADJACENT_TO -> adjacent;
+ case CAUSING -> caused;
+ case DURING -> temporalInherent;
+ case LINKING -> relationshipSource;
+ case TO -> relationshipTarget;
+ };
+ }
}
diff --git a/klab.modeler/src/main/java/org/integratedmodelling/klab/modeler/ModelerImpl.java b/klab.modeler/src/main/java/org/integratedmodelling/klab/modeler/ModelerImpl.java
index a7395e981..ef71543f0 100644
--- a/klab.modeler/src/main/java/org/integratedmodelling/klab/modeler/ModelerImpl.java
+++ b/klab.modeler/src/main/java/org/integratedmodelling/klab/modeler/ModelerImpl.java
@@ -1,6 +1,5 @@
package org.integratedmodelling.klab.modeler;
-import com.jcraft.jsch.Session;
import org.integratedmodelling.common.authentication.scope.AbstractReactiveScopeImpl;
import org.integratedmodelling.common.authentication.scope.AbstractServiceDelegatingScope;
import org.integratedmodelling.common.services.client.engine.EngineImpl;
@@ -55,517 +54,597 @@
import java.util.Map;
/**
- * A {@link UIController} specialized to provide and orchestrate the views and panels that compose the
- * k.Modeler application. Uses an {@link EngineImpl} which will connect to local services if available. Also
- * handles one or more users and keeps a catalog of sessions and contexts, tagging the "current" one in focus
- * in the UI.
- *
- * Call {@link #boot()} in a separate thread when the view is initialized and let the UI events do the rest.
+ * A {@link UIController} specialized to provide and orchestrate the views and panels that compose
+ * the k.Modeler application. Uses an {@link EngineImpl} which will connect to local services if
+ * available. Also handles one or more users and keeps a catalog of sessions and contexts, tagging
+ * the "current" one in focus in the UI.
+ *
+ *
Call {@link #boot()} in a separate thread when the view is initialized and let the UI events
+ * do the rest.
*/
public class ModelerImpl extends AbstractUIController implements Modeler, PropertyHolder {
- private ContextScope currentContext;
- private SessionScope currentSession;
- private List sessions = new ArrayList<>();
- private MultiValueMap contexts = new LinkedMultiValueMap<>();
-
- EngineConfiguration workbench;
- File workbenchDefinition;
- private Map serviceUrls = new HashMap<>();
- private Geometry focalGeometry = Geometry.EMPTY;
- private int contextCount = 0;
- private int sessionCount = 0;
-
- public ModelerImpl() {
- super();
- // read the workbench config
- this.workbenchDefinition = Configuration.INSTANCE.getFileWithTemplate("modeler/workbench.yaml",
- Utils.YAML.asString(new EngineConfiguration()));
- this.workbench = Utils.YAML.load(workbenchDefinition, EngineConfiguration.class);
- }
-
- public ModelerImpl(UI ui) {
- super(ui);
- // TODO read the workbench config - NAH this probably pertains to the IDE
- }
-
- @Override
- public void dispatch(UIReactor sender, UIEvent event, Object... payload) {
-
- // intercept some messages for bookkeeping
- if (event == UIEvent.EngineStatusChanged) {
-
- Engine.Status status = (Engine.Status) payload[0];
-
- for (var capabilities : status.getServicesCapabilities().values()) {
-
- if (capabilities == null) {
- continue;
- }
-
- if (capabilities.getUrl() != null) {
- serviceUrls.put(capabilities.getServiceId(), capabilities.getUrl());
- }
- if (capabilities.getBrokerURI() != null && scope() instanceof AbstractReactiveScopeImpl serviceClient) {
- /*
- * Instrument the service client for messaging. This is pretty involved alas, but the
- * whole
- * matter isn't exactly trivial.
- */
- var client = serviceClient.getService(capabilities.getServiceId());
- if (client != null && client.serviceScope() instanceof AbstractServiceDelegatingScope delegatingScope && delegatingScope.getDelegateChannel() instanceof MessagingChannel messagingChannel) {
- /*
- * If the scope delegates to a messaging channel, set up messaging and link the
- * available service queues to service message dispatchers.
- */
- if (!messagingChannel.isConnected()) {
- messagingChannel.connectToService(capabilities,
- (UserIdentity) user().getIdentity(),
- (message) -> dispatchServerMessage(capabilities, message));
- }
- }
- }
- }
- }
+ private ContextScope currentContext;
+ private SessionScope currentSession;
+ private List sessions = new ArrayList<>();
+ private MultiValueMap contexts = new LinkedMultiValueMap<>();
- super.dispatch(sender, event, payload);
- }
-
- private void dispatchServerMessage(KlabService.ServiceCapabilities capabilities, Message message) {
- // TODO do things
- System.out.println("SERVER MESSAGE FROM " + capabilities.getType() + " " + capabilities.getServiceId() + ": " + message);
- }
-
- @Override
- public Engine createEngine() {
- // TODO first should locate and set the distribution
- return new EngineImpl();
- }
-
- @Override
- protected void createView() {
-
- /*
- pre-built view controllers. View implementations will self-register upon creation.
- */
- registerViewController(new ServicesViewControllerImpl(this));
- registerViewController(new DistributionViewImplController(this));
- registerViewController(new ResourcesNavigatorControllerImpl(this));
- registerViewController(new ContextInspectorControllerImpl(this));
- registerViewController(new AuthenticationViewControllerImpl(this));
- registerViewController(new ContextControllerImpl(this));
- registerViewController(new KnowledgeInspectorControllerImpl(this));
- // TODO etc.
-
- /*
- panel classes
- */
- registerPanelControllerClass(DocumentEditorControllerImpl.class);
- }
+ EngineConfiguration workbench;
+ File workbenchDefinition;
+ private Map serviceUrls = new HashMap<>();
+ private Geometry focalGeometry = Geometry.EMPTY;
+ private int contextCount = 0;
+ private int sessionCount = 0;
- @Override
- public void switchWorkbenchService(UIReactor requestingReactor, KlabService.ServiceCapabilities service) {
- // TODO
- super.switchWorkbenchService(requestingReactor, service);
- }
-
- @Override
- public void switchWorkbench(UIReactor requestingReactor, NavigableContainer container) {
- if (getUI() != null) {
- // we assume that the workspace is mainly intended to show documents and focus on assets.
- // Switching the focal container changes all that, so we first clean everything.
- getUI().cleanWorkspace();
- }
- super.switchWorkbench(requestingReactor, container);
- }
+ public ModelerImpl() {
+ super();
+ // read the workbench config
+ this.workbenchDefinition =
+ Configuration.INSTANCE.getFileWithTemplate(
+ "modeler/workbench.yaml", Utils.YAML.asString(new EngineConfiguration()));
+ this.workbench = Utils.YAML.load(workbenchDefinition, EngineConfiguration.class);
+ }
- @Override
- public void configureWorkbench(UIReactor requestingReactor, NavigableDocument document, boolean shown) {
- // TODO
- super.configureWorkbench(requestingReactor, document, shown);
- }
-
- @Override
- public void setOption(Option option, Object... payload) {
- // TODO validate option
- // TODO react
- }
+ public ModelerImpl(UI ui) {
+ super(ui);
+ // TODO read the workbench config - NAH this probably pertains to the IDE
+ }
- @Override
- public void observe(Object asset, boolean adding) {
+ @Override
+ public void dispatch(UIReactor sender, UIEvent event, Object... payload) {
- if (currentUser() == null) {
- throw new KlabAuthorizationException("Cannot make observations with an invalid user");
- }
+ // intercept some messages for bookkeeping
+ if (event == UIEvent.EngineStatusChanged) {
- /**
- *
- * Use cases:
- *
- * Admitted with a current context or focal scale
- *
- * Concept (from ontology, knowledge explorer/inspector or define)
- * Promote to observable (if countable becomes collective)
- * Observable (from define or knowledge inspector)
- * Observe as expected
- * Model (from namespace or search)
- * Observe as expected
- * Resource from catalog (local or remote)
- * Observe with non-semantic observable
- * Observation from define (can be inline, a URN#ID, other)
- * If adding==true, any existing context is preserved and added to
- * If adding==false, a new context is created and any previous goes out of focus
- * Observation from context tree
- * Just sets the target for the next observations
- *
- * ALL can be either an object or a URN or DOI from inside or outside
- *
- * Admitted w/o a current context or focal scale
- *
- * Observation from define (can be inline, a URN#ID, other)
- *
- * If there is no session, must create a default session & select it
- * If there is no context, must create a default empty context within the session & select it
- */
-
- if (currentSession == null) {
- currentSession = openNewSession("S" + (++sessionCount));
- }
+ Engine.Status status = (Engine.Status) payload[0];
- if (currentContext == null && currentSession != null) {
- currentContext = openNewContext("C" + (++contextCount));
- }
+ for (var capabilities : status.getServicesCapabilities().values()) {
- if (currentContext == null) {
- user().error("cannot create an observation context: aborting", UI.Interactivity.DISPLAY);
- return;
+ if (capabilities == null) {
+ continue;
}
- List