Skip to content

Commit

Permalink
Running ns formatted ActionLang code in tests working
Browse files Browse the repository at this point in the history
  • Loading branch information
retrodaredevil committed Feb 3, 2023
1 parent 3430c81 commit afdfd82
Show file tree
Hide file tree
Showing 40 changed files with 550 additions and 237 deletions.
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ General rule of thumb:
* Why the custom NotNull/Nullable? We want good Kotlin support, and we want to be able to annotate more than just methods.
* If something is exposed through GraphQL and it is not null, always put a `@NotNull` on it.

### Other Conventions
* Use `java.nio.file` rather than `java.io`.
* Use `this.myVariable = requireNonNull(myVariable)` over `requireNonNull(this.myVariable = myVariable)`.
There is legacy code with the ladder.

### Branching
If you are committing directly to the wildmountainfarms/solarthing project, you should be using branch names using
the `my-branch-name` format. Unless you have access to commit to the solarthing project directly,
Expand Down
11 changes: 11 additions & 0 deletions action-lang/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
id 'java'
}

version = '0.0.1-SNAPSHOT'

sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

dependencies {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package me.retrodaredevil.action.lang;

import me.retrodaredevil.action.lang.translators.json.CustomNodeConfiguration;
import me.retrodaredevil.action.lang.translators.json.NodeConfiguration;
import me.retrodaredevil.action.lang.translators.json.SimpleNodeConfiguration;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public final class ActionLangUtil {
private ActionLangUtil() { throw new UnsupportedOperationException(); }

public static final Map<String, NodeConfiguration> NODE_CONFIG_MAP;
static {
Map<String, NodeConfiguration> configMap = new HashMap<>();
configMap.put("racer", CustomNodeConfiguration.RACER);

SimpleNodeConfiguration.Builder builder = createDefaultNodeConfigurationBuilder();

// actions
configMap.put("race", builder.copy().subNodes("racers").build());
configMap.put("scope", builder.copy().linkedNode("action").build());
configMap.put("act", builder.copy().args("name").linkedNode("action").build());
configMap.put("queue", builder.copy().subNodes("actions").build());
configMap.put("parallel", builder.copy().subNodes("actions").build());
configMap.put("print", builder.copy().args("message").linkedNode("expression").build());
configMap.put("call", builder.copy().args("name").build());

configMap.put("init", builder.copy().args("name").linkedNode("expression").build());
configMap.put("init-exp", builder.copy().args("name").linkedNode("expression").build());
configMap.put("set", builder.copy().args("name").linkedNode("expression").build());
configMap.put("set-exp", builder.copy().args("name").linkedNode("expression").build());

configMap.put("all", builder.copy().linkedNode("expression").build());
configMap.put("any", builder.copy().linkedNode("expression").build());
configMap.put("wait", builder.copy().args("duration").build());

// expressions
configMap.put("const", builder.copy().args("value").build());
configMap.put("str", builder.copy().linkedNode("expression").build());
configMap.put("ref", builder.copy().args("name").build());
configMap.put("eval", builder.copy().args("name").build());
configMap.put("join", builder.copy().linkedNode("expression").build());
configMap.put("concat", builder.copy().subNodes("expressions").build());
// TODO consider adding union operation and other set operations: https://www.math.net/union

NODE_CONFIG_MAP = Collections.unmodifiableMap(configMap);
}
public static SimpleNodeConfiguration.Builder createDefaultNodeConfigurationBuilder() {
// we have the ability to modify the default builder in the future if we would like to
return SimpleNodeConfiguration.builder();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import me.retrodaredevil.action.Action;
import me.retrodaredevil.action.lang.antlr.NodeParser;
import me.retrodaredevil.action.lang.translators.json.CustomNodeConfiguration;
import me.retrodaredevil.action.lang.translators.json.JsonNodeTranslator;
import me.retrodaredevil.action.lang.translators.json.NodeConfiguration;
import me.retrodaredevil.action.lang.translators.json.SimpleConfigurationProvider;
import me.retrodaredevil.action.lang.translators.json.SimpleNodeConfiguration;
import me.retrodaredevil.action.node.ActionNode;
import me.retrodaredevil.action.node.environment.ActionEnvironment;
import me.retrodaredevil.action.node.environment.InjectEnvironment;
Expand All @@ -20,51 +17,11 @@

import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;

public class ActionLangTest {

private static final ObjectMapper MAPPER = new ObjectMapper();
private static final Map<String, NodeConfiguration> CONFIG_MAP;
static {
Map<String, NodeConfiguration> configMap = new HashMap<>();
configMap.put("racer", CustomNodeConfiguration.RACER);

// actions
configMap.put("race", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), "racers", null));
configMap.put("scope", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), null, "action"));
configMap.put("act", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, "action"));
configMap.put("queue", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), "actions", null));
configMap.put("parallel", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), "actions", null));
configMap.put("print", new SimpleNodeConfiguration("type", Arrays.asList("message"), emptyMap(), null, "expression"));
configMap.put("log", new SimpleNodeConfiguration("type", Arrays.asList("message"), emptyMap(), null, null));
configMap.put("call", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, null));

configMap.put("init", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, "expression"));
configMap.put("init-exp", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, "expression"));
configMap.put("set", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, "expression"));
configMap.put("set-exp", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, "expression"));

configMap.put("all", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), null, "expression"));
configMap.put("any", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), null, "expression"));
configMap.put("wait", new SimpleNodeConfiguration("type", Arrays.asList("duration"), emptyMap(), null, null));

// expressions
configMap.put("const", new SimpleNodeConfiguration("type", Arrays.asList("value"), emptyMap(), null, null));
configMap.put("str", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), null, "expression"));
configMap.put("ref", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, null));
configMap.put("eval", new SimpleNodeConfiguration("type", Arrays.asList("name"), emptyMap(), null, null));
configMap.put("join", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), null, "expression"));
configMap.put("union", new SimpleNodeConfiguration("type", emptyList(), emptyMap(), "expressions", null));
CONFIG_MAP = Collections.unmodifiableMap(configMap);
}

@Test
void testCode() throws IOException {
Expand All @@ -73,8 +30,8 @@ void testCode() throws IOException {
));

NodeTranslator<JsonNode> translator = new JsonNodeTranslator(new SimpleConfigurationProvider(
new SimpleNodeConfiguration("type", emptyList(), Collections.emptyMap(), null, null),
CONFIG_MAP
ActionLangUtil.createDefaultNodeConfigurationBuilder().build(),
ActionLangUtil.NODE_CONFIG_MAP
));
System.out.println(translator.translate(node));
}
Expand All @@ -90,8 +47,8 @@ private void runResource(String name) throws IOException {
));

NodeTranslator<JsonNode> translator = new JsonNodeTranslator(new SimpleConfigurationProvider(
new SimpleNodeConfiguration("type", emptyList(), Collections.emptyMap(), null, null),
CONFIG_MAP
ActionLangUtil.createDefaultNodeConfigurationBuilder().build(),
ActionLangUtil.NODE_CONFIG_MAP
));
JsonNode json = translator.translate(node);
System.out.println(json);
Expand Down
4 changes: 3 additions & 1 deletion action-lang/src/test/resources/test_code2.ns
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
scope : queue {
print "Hello there how are you?"
log("Cool message", summary = true); call someAction
// This code does not have to be run, just has to be parsed
// This code cannot contain SolarThing specific nodes
call someAction
}
6 changes: 3 additions & 3 deletions action-lang/src/test/resources/test_code3.ns
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ scope : queue {
init x : const 3
init y : ref x
init-exp z : ref x
print : join : union { const "x: "; str : ref x }
print : join : concat { const "x: "; str : ref x }
set x : const 4
print : join : union { const "y: "; str : ref y }
print : join : union { const "z: "; str : ref z }
print : join : concat { const "y: "; str : ref y }
print : join : concat { const "z: "; str : ref z }

call doSomething
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ public class WithLockActionNode implements ActionNode {
private final ActionNode finallyAction;

public WithLockActionNode(
@JsonProperty("name") String lockName,
@JsonProperty(value = "set") String lockSetName,
@JsonProperty("action") ActionNode action,
@JsonProperty(value = "name", required = true) String lockName,
@JsonProperty("set") String lockSetName,
@JsonProperty(value = "action", required = true) ActionNode action,
@JsonProperty("timeout") ActionNode timeoutAction,
@JsonProperty("ontimeout") ActionNode onTimeoutAction,
@JsonProperty("finally") ActionNode finallyAction) {
requireNonNull(this.lockName = lockName);
this.lockName = requireNonNull(lockName);
this.lockSetName = lockSetName;
requireNonNull(this.action = action);
this.action = requireNonNull(action);
this.timeoutAction = timeoutAction == null ? PassActionNode.getInstance() : timeoutAction;
this.onTimeoutAction = onTimeoutAction == null ? PassActionNode.getInstance() : onTimeoutAction;
this.finallyAction = finallyAction == null ? PassActionNode.getInstance() : finallyAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface Expression {
* @return The known type of the expression or null. Null represents that the type is unknown until {@link #evaluate()} is called
*/
default ExpressionType getType() {
// TODO determine if this method is even needed. (When is it actually needed by something and when does it get in the way)
// As of 2023.02.02 we don't even implement it everywhere since null is a valid value in any scenario with the recent introduction of the ref implementation
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

import static java.util.Objects.requireNonNull;

@JsonTypeName("union")
public class UnionExpressionNode implements ExpressionNode {
@JsonTypeName("concat")
public class ConcatExpressionNode implements ExpressionNode {
private final List<ExpressionNode> expressionNodes;

@JsonCreator
public UnionExpressionNode(@JsonProperty(value = "expressions", required = true) List<ExpressionNode> expressionNodes) {
public ConcatExpressionNode(@JsonProperty(value = "expressions", required = true) List<ExpressionNode> expressionNodes) {
this.expressionNodes = requireNonNull(expressionNodes);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
@JsonSubTypes.Type(VariableReferenceExpressionNode.class),
@JsonSubTypes.Type(ToStringExpressionNode.class),
@JsonSubTypes.Type(JoinStringExpressionNode.class),
@JsonSubTypes.Type(UnionExpressionNode.class),
@JsonSubTypes.Type(ConcatExpressionNode.class),
})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface ExpressionNode {
Expand Down
4 changes: 1 addition & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ project(":common"){
apply plugin: 'java'
dependencies {
api project(":core")
api project(":action-node")
api project(":action-lang")
annotationProcessor project(":process-annotations")
}
}
Expand All @@ -240,7 +240,6 @@ project(":client"){
api project(":core")
api project(":common")
api project(":serviceapi")
api project(":action-node")
annotationProcessor project(":process-annotations")
}
test {
Expand Down Expand Up @@ -276,7 +275,6 @@ project(":graphql"){
api project(":core")
api project(":common")
api project(":serviceapi")
api project(":action-node")
annotationProcessor project(":process-annotations")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.retrodaredevil.solarthing.config.options;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import me.retrodaredevil.solarthing.actions.config.ActionFormat;
import me.retrodaredevil.solarthing.actions.config.ActionReference;

import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

import static java.util.Objects.requireNonNull;

public final class ActionConfig {
public static final ActionConfig EMPTY = new ActionConfig(Collections.emptyList());
private final List<Entry> entries;

@JsonCreator
public ActionConfig(@JsonProperty(value = "entries", required = true) List<Entry> entries) {
this.entries = requireNonNull(entries);
}

public List<Entry> getEntries() {
return entries;
}

public static final class Entry {
private final ActionReference actionReference;
private final boolean runOnce;

@JsonCreator
public Entry(
@JsonProperty(value = "path", required = true) Path path,
@JsonProperty("format") ActionFormat format,
@JsonProperty("once") Boolean runOnce
) {
this.actionReference = new ActionReference(
path,
format == null ? ActionFormat.NOTATION_SCRIPT : format
);
this.runOnce = Boolean.TRUE.equals(runOnce); // by default false
}

public ActionReference getActionReference() {
return actionReference;
}

public boolean isRunOnce() {
return runOnce;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,15 @@
* be executed each "iteration".
*/
public interface ActionsOption extends ProgramOptions {
/**
* A legacy configuration option that currently is still supported, but will be removed in a future version
*/
List<File> getActionNodeFiles();

/**
* This will not be null, but may be {@link ActionConfig#EMPTY} by default.
*
* @return The {@link ActionConfig}.
*/
ActionConfig getActionConfig();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.io.File;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

import static java.util.Objects.requireNonNull;
Expand All @@ -14,7 +15,9 @@
@JsonExplicit
public class AutomationProgramOptions extends DatabaseTimeZoneOptionBase implements ActionsOption {
@JsonProperty("actions")
private List<File> actionNodeFiles;
private List<File> actionNodeFiles = Collections.emptyList();
@JsonProperty("action_config")
private ActionConfig actionConfig = ActionConfig.EMPTY;

@JsonProperty("period")
private String periodDurationString = "PT5S";
Expand All @@ -26,8 +29,14 @@ public ProgramType getProgramType() {

@Override
public List<File> getActionNodeFiles() {
return requireNonNull(actionNodeFiles);
return requireNonNull(actionNodeFiles, "You cannot supply a null value here!");
}

@Override
public ActionConfig getActionConfig() {
return requireNonNull(actionConfig);
}

public long getPeriodMillis() {
return Duration.parse(periodDurationString).toMillis();
}
Expand Down
Loading

0 comments on commit afdfd82

Please sign in to comment.