diff --git a/pom.xml b/pom.xml
index 64d3165..881733a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
hmi.flipper2.0
flipper2.0
- 0.2
+ 1.0
jar
${project.groupId}:${project.artifactId}
@@ -59,7 +59,7 @@
org.hamcrest
- hamcrest-core
+ hamcrest
2.2
test
@@ -73,16 +73,31 @@
javax.json
1.1.4
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.11.1
+
org.postgresql
postgresql
- 42.2.5
+ 42.2.14
org.slf4j
slf4j-api
1.7.30
+
+ org.graalvm.js
+ js-scriptengine
+ 20.1.0
+
+
+ org.graalvm.js
+ js
+ 20.1.0
+
UTF-8
diff --git a/src/main/java/hmi/flipper2/FlipperException.java b/src/main/java/hmi/flipper2/FlipperException.java
index b0b7a21..5531706 100644
--- a/src/main/java/hmi/flipper2/FlipperException.java
+++ b/src/main/java/hmi/flipper2/FlipperException.java
@@ -28,6 +28,8 @@
import org.xml.sax.SAXException;
+import static hmi.flipper2.TemplateController.logger;
+
public class FlipperException extends Exception {
/**
@@ -65,6 +67,7 @@ public FlipperException(Exception ex) {
public FlipperException(Exception ex, String extra) {
_init(ex);
this.extra = extra;
+ logger.error(this.extra);
}
public FlipperException(SAXException ex) {
@@ -97,12 +100,12 @@ public void registerCurrentTemplate(String current_tf, String current_id, String
public static void handle(FlipperException e) {
if ( e.extra != null )
- System.err.println(e.extra);
+ logger.error(e.extra);
if ( e.currentInfo != null )
- System.err.println(e.currentInfo);
- System.err.println("!Caught Exception: "+e.text);
+ logger.error(e.currentInfo);
+ logger.error("!Caught Exception: "+e.text);
if (e.stack != null )
- System.err.println("!Stack: \n"+e.stack);
+ logger.error("!Stack: \n"+e.stack);
}
}
diff --git a/src/main/java/hmi/flipper2/Is.java b/src/main/java/hmi/flipper2/Is.java
index f363bdc..e711f7a 100644
--- a/src/main/java/hmi/flipper2/Is.java
+++ b/src/main/java/hmi/flipper2/Is.java
@@ -27,6 +27,8 @@
import hmi.flipper2.javascript.JsExpression;
import hmi.flipper2.postgres.Database;
+import static hmi.flipper2.TemplateController.logger;
+
public class Is extends JsEngine {
private Database db;
@@ -75,7 +77,7 @@ public void rollback() throws FlipperException {
for (Map.Entry entry : this.is_tf_table.entrySet()) {
if (entry.getValue().is_updated) {
entry.getValue().is_updated = false;
- System.out.println("INCOMPLETE:Is:rollback: should re-read is after db rollback");
+ logger.warn("INCOMPLETE:Is:rollback: should re-read is after db rollback");
}
}
}
diff --git a/src/main/java/hmi/flipper2/Main.java b/src/main/java/hmi/flipper2/Main.java
index fc107f7..3af8054 100644
--- a/src/main/java/hmi/flipper2/Main.java
+++ b/src/main/java/hmi/flipper2/Main.java
@@ -55,7 +55,7 @@ public static void main(String[] args) {
int count = 0;
boolean changed = true;
while( changed && (count < maxcount) ) {
- System.out.println("\nIS:\n---\n"+tc.getIs("is")+"\n");
+ logger.debug("\nIS:\n---\n"+tc.getIs("is")+"\n");
changed = tc.checkTemplates();
count++;
}
diff --git a/src/main/java/hmi/flipper2/Template.java b/src/main/java/hmi/flipper2/Template.java
index 3a1e3fd..4b0ec1e 100644
--- a/src/main/java/hmi/flipper2/Template.java
+++ b/src/main/java/hmi/flipper2/Template.java
@@ -46,6 +46,8 @@
import hmi.flipper2.value.JavaValueList;
import hmi.flipper2.value.PersistentJavaValue;
+import static hmi.flipper2.TemplateController.logger;
+
public class Template extends FlipperObject {
public TemplateFile tf;
@@ -299,7 +301,7 @@ public Set flowIn() {
for(EffectList l : listOfEffectList)
res.addAll(l.flowIn());
this.dfin = res;
- System.out.println("TEMPLATE-IN["+id()+"]="+dfin);
+ logger.debug("TEMPLATE-IN["+id()+"]="+dfin);
return res;
}
@@ -311,7 +313,7 @@ public Set flowOut() {
for (EffectList l : listOfEffectList)
res.addAll(l.flowOut());
this.dfout = res;
- System.out.println("TEMPLATE-OUT["+id()+"]="+dfout);
+ logger.debug("TEMPLATE-OUT["+id()+"]="+dfout);
return res;
}
diff --git a/src/main/java/hmi/flipper2/TemplateController.java b/src/main/java/hmi/flipper2/TemplateController.java
index 221ea8f..7521644 100644
--- a/src/main/java/hmi/flipper2/TemplateController.java
+++ b/src/main/java/hmi/flipper2/TemplateController.java
@@ -36,6 +36,8 @@
import hmi.flipper2.effect.EffectList;
import hmi.flipper2.postgres.Database;
import hmi.flipper2.sax.SimpleSAXParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* This class is the main Flipper interface class. You can create/modify/destroy Flipper Templatecontollers using this class.
@@ -47,6 +49,8 @@
*/
public class TemplateController {
+
+ public static Logger logger = LoggerFactory.getLogger(TemplateController.class.getName());
/**
* This method creates a new TemplateController.
@@ -103,8 +107,6 @@ public static TemplateController create(String name, String descr, Database db,
* The name of the existing TemplateController in the Database.
* @param db
* The Database the TemplateController is stored. When db == null the method does nothing.
- * @param jslibs
- * String array of additional js libs to preload.
* @exception FlipperException
* On all errors.
*/
@@ -202,7 +204,7 @@ public void setDebugger(FlipperDebugger fd) {
public void setDebugger(FlipperDebugger fd, boolean onoff) {
if ( !Config.debugging && fd!=null )
- System.err.println("WARNING: Setting FlipperDebugger with Config.debugging=false");
+ logger.error("WARNING: Setting FlipperDebugger with Config.debugging=false");
this.persistent_dbg = fd;
switchDebugger(onoff);
}
@@ -324,9 +326,15 @@ public boolean checkTemplates(String templateFilter) throws FlipperException {
this.dbg.start_CheckTemplates(this.name, null);
}
for (Template template : filterTemplates(this.base_templates, templateFilter) ) {
+ long startTime = System.nanoTime();
if ( Config.debugging && this.dbg != null )
this.dbg.start_CheckTemplate(template.id(), null);
changed = checkPreconditions(template, Behaviour.IMMEDIATE_EFFECT) || changed;
+ long endTime = System.nanoTime();
+ long duration = (endTime - startTime); //divide by 1000000 to get milliseconds.
+ if(duration/1000000>50){
+ logger.debug("Duration Template, ID: " + template.id() + " and duration: " + duration/1000000);
+ }
// while ( this.conditional_stack != null ) {
// Template toCheck = this.conditional_stack;
// this.conditional_stack = this.conditional_stack.pop();
diff --git a/src/main/java/hmi/flipper2/TemplateFile.java b/src/main/java/hmi/flipper2/TemplateFile.java
index efb4311..8764be3 100644
--- a/src/main/java/hmi/flipper2/TemplateFile.java
+++ b/src/main/java/hmi/flipper2/TemplateFile.java
@@ -34,6 +34,8 @@
import hmi.flipper2.sax.SimpleElement;
import hmi.flipper2.sax.SimpleSAXParser;
+import static hmi.flipper2.TemplateController.logger;
+
public class TemplateFile extends FlipperObject {
public int tfid = -1;
@@ -184,7 +186,7 @@ public Set flowIn() {
res.addAll(t.flowIn());
this.dfin = res;
this.dfin_tf = is_var2templatefile(res);
- System.out.println("TF-IN["+id()+"]="+dfin_tf);
+ logger.debug("TF-IN["+id()+"]="+dfin_tf);
return res;
}
@@ -196,7 +198,7 @@ public Set flowOut() {
res.addAll(t.flowOut());
this.dfout = res;
this.dfout_tf = is_var2templatefile(res);
- System.out.println("TF-OUT["+id()+"]="+dfout_tf);
+ logger.debug("TF-OUT["+id()+"]="+dfout_tf);
return res;
}
}
diff --git a/src/main/java/hmi/flipper2/TestScenarios.java b/src/main/java/hmi/flipper2/TestScenarios.java
index 012e48e..da9a7b1 100644
--- a/src/main/java/hmi/flipper2/TestScenarios.java
+++ b/src/main/java/hmi/flipper2/TestScenarios.java
@@ -20,6 +20,8 @@
import hmi.flipper2.postgres.Database;
+import static hmi.flipper2.TemplateController.logger;
+
public class TestScenarios {
public static void main(String[] args) {
@@ -38,9 +40,9 @@ public static void openCheckXCloseDestroy() {
//
for(int i=0; i<5; i++) {
tc = new TemplateController(scenario, db);
- // System.out.println("\nBEFORE IS:\n---\n"+tc.getIs("is")+"\n");
+ logger.debug("\nBEFORE IS:\n---\n"+tc.getIs("is")+"\n");
tc.checkTemplates();
- System.out.println("\nIS:\n---\n"+tc.getIs("is")+"\n");
+ logger.debug("\nIS:\n---\n"+tc.getIs("is")+"\n");
tc.close();
}
// TemplateController.destroy(scenario, db);
diff --git a/src/main/java/hmi/flipper2/dataflow/DataFlow.java b/src/main/java/hmi/flipper2/dataflow/DataFlow.java
index d2395e4..f6e8638 100644
--- a/src/main/java/hmi/flipper2/dataflow/DataFlow.java
+++ b/src/main/java/hmi/flipper2/dataflow/DataFlow.java
@@ -74,7 +74,7 @@ else if ( r == EMPTY )
// public static void main(String[] args) {
// Set res = extractRefs("is.a \"xis.\" en is.y.v._z is.x");
-// System.out.println("RES:" + res);
+// logger.debug("RES:" + res);
// }
}
diff --git a/src/main/java/hmi/flipper2/debugger/CpuMemoryUsage.java b/src/main/java/hmi/flipper2/debugger/CpuMemoryUsage.java
index 258ad07..75d1bd5 100644
--- a/src/main/java/hmi/flipper2/debugger/CpuMemoryUsage.java
+++ b/src/main/java/hmi/flipper2/debugger/CpuMemoryUsage.java
@@ -28,6 +28,8 @@
import hmi.flipper2.TemplateController;
+import static hmi.flipper2.TemplateController.logger;
+
public class CpuMemoryUsage {
enum Channel {
@@ -91,7 +93,7 @@ public double getProcessCpuLoad() {
// returns a percentage value with 1 decimal point precision
return ((int) (value * 1000) / 10.0);
} catch (Exception e) {
- System.out.println("EXCEPTION: " + e);
+ logger.error("EXCEPTION: " + e);
return 0.0;
}
}
diff --git a/src/main/java/hmi/flipper2/debugger/FlipperDebugger.java b/src/main/java/hmi/flipper2/debugger/FlipperDebugger.java
index 08b8283..e4d33a1 100644
--- a/src/main/java/hmi/flipper2/debugger/FlipperDebugger.java
+++ b/src/main/java/hmi/flipper2/debugger/FlipperDebugger.java
@@ -20,6 +20,8 @@
import hmi.flipper2.TemplateController;
+import static hmi.flipper2.TemplateController.logger;
+
public class FlipperDebugger {
enum Kind {
@@ -38,14 +40,14 @@ public void handle_state(FlipperState s) {
boolean verbose = false;
if ( verbose )
- System.out.println("#"+s.action.name() + "\t" + s.id + "\t"+pt(s.duration()));
+ logger.info("#"+s.action.name() + "\t" + s.id + "\t"+pt(s.duration()));
switch (s.action) {
case CheckTemplates: {
- System.out.println("[");
+ logger.info("[");
for (Action a : Action.values()) {
- System.out.println("\t+ Total Time: "+ String.format("%1$14s", a.name()) + " = " + pt(this.totalTimes[a.ordinal()]));
+ logger.info("\t+ Total Time: "+ String.format("%1$14s", a.name()) + " = " + pt(this.totalTimes[a.ordinal()]));
}
- System.out.println("]");
+ logger.info("]");
}
break;
case CheckTemplate:
@@ -73,12 +75,12 @@ private void handle_startstop(Kind kind, Action action, String other_action, Str
state.startTime = System.nanoTime();
state.startArg = arg;
if ( verbose )
- System.out.println(kind.name() + "\t" + String.format("%1$14s", action.name()) + "\t" + id);
+ logger.info(kind.name() + "\t" + String.format("%1$14s", action.name()) + "\t" + id);
} else {
state.stopTime = System.nanoTime();
state.stopArg = arg;
if ( verbose )
- System.out.println(kind.name() + "\t" + String.format("%1$14s", action.name()) + "\t" + id + "\t("+pt(state.duration())+")");
+ logger.info(kind.name() + "\t" + String.format("%1$14s", action.name()) + "\t" + id + "\t("+pt(state.duration())+")");
this.totalTimes[action.ordinal()] += state.duration();
handle_state(state);
state = state.pop();
diff --git a/src/main/java/hmi/flipper2/effect/TemplateEffect.java b/src/main/java/hmi/flipper2/effect/TemplateEffect.java
index c57157d..574be90 100644
--- a/src/main/java/hmi/flipper2/effect/TemplateEffect.java
+++ b/src/main/java/hmi/flipper2/effect/TemplateEffect.java
@@ -24,6 +24,8 @@
import hmi.flipper2.Is;
import hmi.flipper2.dataflow.DataFlow;
+import static hmi.flipper2.TemplateController.logger;
+
public class TemplateEffect extends Effect {
private String regexpr;
@@ -34,8 +36,8 @@ public TemplateEffect(String id, String regexpr, String isregexpr) throws Flippe
throw new FlipperException("TemplateEffect cannot have both regexpr and isregexpr");
this.regexpr = regexpr;
this.isregexpr = isregexpr;
- // System.out.println("regexpr="+this.regexpr);
- // System.out.println("isregexpr="+this.isregexpr);
+ logger.debug("regexpr="+this.regexpr);
+ logger.debug("isregexpr="+this.isregexpr);
}
@Override
diff --git a/src/main/java/hmi/flipper2/environment/BaseFlipperEnvironment.java b/src/main/java/hmi/flipper2/environment/BaseFlipperEnvironment.java
new file mode 100644
index 0000000..261a99d
--- /dev/null
+++ b/src/main/java/hmi/flipper2/environment/BaseFlipperEnvironment.java
@@ -0,0 +1,113 @@
+package hmi.flipper2.environment;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+public abstract class BaseFlipperEnvironment implements IFlipperEnvironment {
+
+ protected static org.slf4j.Logger logger = LoggerFactory.getLogger(BaseFlipperEnvironment.class.getName());
+
+ private String id;
+ protected BlockingQueue outQueue = null;
+
+ public BaseFlipperEnvironment() {
+ outQueue = new LinkedBlockingQueue<>(256);
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public boolean hasMessage() {
+ return !outQueue.isEmpty();
+ }
+
+ @Override
+ public FlipperEnvironmentMessageJSON getMessage() throws InterruptedException {
+ FlipperEnvironmentMessageJSON message = outQueue.take();
+ return message;
+ }
+
+ protected FlipperEnvironmentMessageJSON buildResponse(FlipperEnvironmentMessageJSON responseTo, JsonNode params) {
+ FlipperEnvironmentMessageJSON msg = new FlipperEnvironmentMessageJSON(responseTo.cmd, responseTo.environment, responseTo.msgId, params);
+ return msg;
+ }
+
+ protected void enqueueMessage(FlipperEnvironmentMessageJSON msg) {
+ if (outQueue.remainingCapacity() < 1) {
+ outQueue.poll();
+ logger.warn("OutQueue is full, dropping oldest message.");
+ }
+ outQueue.add(msg);
+ }
+
+ protected void enqueueMessage(JsonNode params, String cmd, String msgId) {
+ FlipperEnvironmentMessageJSON msg = new FlipperEnvironmentMessageJSON(cmd, this.getId(), msgId, params);
+ enqueueMessage(msg);
+ }
+
+ protected String enqueueMessage(JsonNode params, String cmd) {
+ String msgId = "M"+ UUID.randomUUID();
+ enqueueMessage(params, cmd, msgId);
+ return msgId;
+ }
+
+ @Override
+ public abstract FlipperEnvironmentMessageJSON onMessage(FlipperEnvironmentMessageJSON fenvmsg) throws Exception;
+
+ @Override
+ public abstract void setRequiredEnvironments(IFlipperEnvironment[] envs) throws Exception;
+
+ @Override
+ public void init(JsonNode params) throws Exception {
+ throw new Exception("Not implemented init function in this environment.");
+ }
+
+ @Override
+ public void init(JsonNode params, Connection connection) throws Exception {
+ this.init(params);
+ }
+
+ // Return value of "loaderClass", and adds all other values in spec to pout
+ public static Properties getGMLProperties(JsonNode spec) {
+ Properties res = new Properties();
+ JsonNode jnprops = null;
+ if (spec.has("properties")) {
+ jnprops = spec.get("properties");
+ } else {
+ return null;
+ }
+ Iterator fieldNames = jnprops.fieldNames();
+ while (fieldNames.hasNext()) {
+ String fieldName = fieldNames.next();
+ res.put(fieldName, jnprops.get(fieldName).asText());
+ }
+ return res;
+ }
+
+ public static String getGMLClass(JsonNode spec) {
+ String loaderClass = "";
+ if (spec.has("loaderClass")) {
+ loaderClass = spec.get("loaderClass").asText();
+ } else {
+ return null;
+ }
+ return loaderClass;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/hmi/flipper2/environment/FlipperEnvironmentBus.java b/src/main/java/hmi/flipper2/environment/FlipperEnvironmentBus.java
new file mode 100644
index 0000000..1fc0877
--- /dev/null
+++ b/src/main/java/hmi/flipper2/environment/FlipperEnvironmentBus.java
@@ -0,0 +1,260 @@
+package hmi.flipper2.environment;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/* Example environmentSpec:
+{
+ "environments": [
+ {
+ "id":"bml", "loader":"eu.couch.hmi.environments.BMLEnvironment", "requiredloaders": [],
+ "params": {
+ "publishBmlFeedback": true,
+ "middleware": {
+ "loaderClass": "nl.utwente.hmi.middleware.activemq.ActiveMQMiddlewareLoader",
+ "properties": {
+ "iTopic": "COUCH/BML/FEEDBACK/ASAP",
+ "oTopic": "COUCH/BML/REQUEST/ASAP",
+ "amqBrokerURI": "tcp://localhost:61616"
+ }
+ }
+ }
+ }, {
+ "id":"dgep", "loader":"eu.couch.hmi.environments.DGEPEnvironment", "requiredloaders": [],
+ "params": {
+ "dgepCtrlMiddleware": {
+ "loaderClass": "nl.utwente.hmi.middleware.activemq.ActiveMQMiddlewareLoader",
+ "properties": {
+ "iTopic": "DGEP/response",
+ "oTopic": "DGEP/requests",
+ "amqBrokerURI": "tcp://localhost:61616"
+ }
+ },
+ "dgepMovesMiddleware": {
+ "loaderClass": "nl.utwente.hmi.middleware.activemq.ActiveMQMiddlewareLoader",
+ "properties": {
+ "iTopic": "DGEP/dialogue_moves",
+ "oTopic": "DGEP/requests",
+ "amqBrokerURI": "tcp://localhost:61616"
+ }
+ }
+ }
+ }, {
+ "id":"flipperintents", "loader":"eu.couch.hmi.environments.FlipperIntentPlannerEnvironment", "requiredloaders": [ "bml" ],
+ "params": {}
+ }, {
+ "id":"ui", "loader":"eu.couch.hmi.environments.UIEnvironment", "requiredloaders": [ "dgep" ],
+ "params": {
+ "middleware": {
+ "loaderClass": "nl.utwente.hmi.middleware.activemq.ActiveMQMiddlewareLoader",
+ "properties": {
+ "iTopic": "COUCH/UI/REQUESTS",
+ "oTopic": "COUCH/UI/STATE",
+ "amqBrokerURI": "tcp://localhost:61616"
+ }
+ }
+ }
+ }, {
+ "id":"dialogueloader", "loader":"eu.couch.hmi.environments.DialogueLoaderEnvironment", "requiredloaders": [ "dgep", "flipperintents", "ui", "bml" ],
+ "params": {}
+ }
+ ]
+}
+*/
+
+class EnvironmentSpec {
+ public EnvironmentLoaderSpec[] environments;
+}
+
+class EnvironmentLoaderSpec {
+ public String id;
+ public String loader;
+ public String[] requiredloaders;
+ public JsonNode params;
+}
+
+public class FlipperEnvironmentBus {
+
+ private static org.slf4j.Logger logger = LoggerFactory.getLogger(FlipperEnvironmentBus.class.getName());
+
+ private Map environments;
+ private ObjectMapper om;
+ private Connection connection;
+
+ public FlipperEnvironmentBus() {
+ environments = new HashMap<>();
+ om = new ObjectMapper();
+ om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+ public FlipperEnvironmentBus(Connection connection){
+ this();
+ this.connection = connection;
+ }
+
+
+ public boolean init(String specString) {
+ try {
+ JsonNode jn = om.readTree(specString);
+ EnvironmentSpec spec = om.treeToValue(jn, EnvironmentSpec.class);
+ loadSpec(spec);
+ } catch (IOException | EnvironmentLoadException e) {
+ logger.error("Failed to init FlipperEnvironmentBus, invalid spec? ", e);
+ return false;
+ }
+ logger.info("Initialized with "+environments.size()+" environments.");
+ return true;
+ }
+
+ public boolean hasMessages() {
+ for (IFlipperEnvironment env : environments.values()) {
+ if (env.hasMessage()) return true;
+ }
+ return false;
+ }
+
+ public String getMessages() {
+ List res = new ArrayList();
+ for (IFlipperEnvironment env : environments.values()) {
+ while (env.hasMessage()) {
+ try {
+ res.add(env.getMessage());
+ } catch (Exception e) {
+ logger.warn("Failed to get message from environment: "+env.getId(), e);
+ }
+ }
+ }
+
+ try {
+ return om.writeValueAsString(res.toArray(new FlipperEnvironmentMessageJSON[0]));
+ } catch (JsonProcessingException e) {
+ logger.warn("Failed to return queue messages from environments ", e);
+ }
+ return "[]";
+ }
+
+ public String sendMessages(String msgsJson) {
+ logger.debug("received messages:\n "+msgsJson);
+ List res = new ArrayList();
+ try {
+ JsonNode jn = om.readTree(msgsJson);
+ FlipperEnvironmentMessageJSON[] msgs = om.treeToValue(jn, FlipperEnvironmentMessageJSON[].class);
+ for (FlipperEnvironmentMessageJSON msg : msgs) {
+ FlipperEnvironmentMessageJSON _res = sendMessage(msg);
+ if (_res != null) res.add(_res);
+ }
+ } catch (IOException e) {
+ logger.error("Failed to process messages "+msgsJson, e);
+ }
+
+ try {
+ return om.writeValueAsString(res.toArray(new FlipperEnvironmentMessageJSON[0]));
+ } catch (Exception e) {
+ logger.warn("Failed to return responses from environments ", e);
+ }
+
+ return "[]";
+ }
+
+ public FlipperEnvironmentMessageJSON sendMessage(FlipperEnvironmentMessageJSON msg) {
+ FlipperEnvironmentMessageJSON _result = null;
+ String targetEnv = "";
+ if (environments.containsKey(msg.environment)) {
+ targetEnv = msg.environment;
+ try {
+ logger.debug("Forwarding message of type {} to environment {}.",msg.cmd,msg.environment);
+ _result = environments.get(targetEnv).onMessage(msg);
+ } catch (Exception e) {
+ logger.error("Environment "+targetEnv+" failed (error: {}) to handle message: {}", e, msg);
+ e.printStackTrace();
+ }
+ } else {
+ logger.warn("Environment ID unknown: {}", msg.environment);
+ }
+ return _result;
+ }
+
+ public String sendMessage(String msgJson) {
+ String result = "{}";
+ try {
+ JsonNode msgNode = om.readTree(msgJson);
+ FlipperEnvironmentMessageJSON msg = om.treeToValue(msgNode,FlipperEnvironmentMessageJSON.class);
+ FlipperEnvironmentMessageJSON _result = sendMessage(msg);
+ if (_result != null) {
+ result = om.writeValueAsString(result);
+ }
+ } catch (IOException e) {
+ logger.error("Failed to process message request: ", e, msgJson);
+ result = "{}";
+ }
+
+ return result;
+ }
+
+ public void loadSpec(EnvironmentSpec spec) throws EnvironmentLoadException {
+ for (EnvironmentLoaderSpec lspec : spec.environments) {
+ try {
+ if (environments.containsKey(lspec.id)) {
+ throw new EnvironmentLoadException("Duplicate environment id: "+lspec.id);
+ }
+ IFlipperEnvironment env = instantiateEnvironment(lspec.loader);
+ env.setId(lspec.id);
+ List requiredEnvs = new ArrayList();
+ for (String envId : lspec.requiredloaders) {
+ if (!environments.containsKey(envId))
+ throw new EnvironmentLoadException("Required Loader ID unknown: "+envId);
+ requiredEnvs.add(environments.get(envId));
+ }
+ try {
+ env.setRequiredEnvironments(requiredEnvs.toArray(new IFlipperEnvironment[0]));
+ if(this.connection != null){
+ env.init(lspec.params,this.connection);
+ }
+ else{
+ env.init(lspec.params);
+ }
+ } catch (Exception e) {
+ System.out.println("E: " + e.getMessage());
+ throw new EnvironmentLoadException("Failed to init environment "+lspec.id+": "+e.getMessage());
+ }
+ logger.debug("Initialized environment: "+lspec.loader+" ("+env.getId()+")");
+ environments.put(lspec.id, env);
+ } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException ex) {
+ Logger.getLogger(FlipperEnvironmentBus.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+
+ public IFlipperEnvironment instantiateEnvironment(final String className) throws EnvironmentLoadException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
+ try{
+ return IFlipperEnvironment.class.cast(Class.forName(className).getDeclaredConstructor().newInstance());
+ } catch(InstantiationException
+ | IllegalAccessException
+ | ClassNotFoundException e) {
+ throw new EnvironmentLoadException("Failed to instantiate FlipperEnvironment with classname "+className+": "+e.getMessage());
+ }
+ }
+
+}
+
+class EnvironmentLoadException extends Exception {
+ private static final long serialVersionUID = 8290847513890592695L;
+
+ public EnvironmentLoadException(String errorMessage) {
+ super(errorMessage);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/hmi/flipper2/environment/FlipperEnvironmentMessageJSON.java b/src/main/java/hmi/flipper2/environment/FlipperEnvironmentMessageJSON.java
new file mode 100644
index 0000000..d11dd97
--- /dev/null
+++ b/src/main/java/hmi/flipper2/environment/FlipperEnvironmentMessageJSON.java
@@ -0,0 +1,26 @@
+package hmi.flipper2.environment;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+public class FlipperEnvironmentMessageJSON {
+
+ public String cmd;
+ public String environment;
+ public String msgId;
+
+ public JsonNode params;
+
+ public FlipperEnvironmentMessageJSON(String cmd, String environment, String msgId, JsonNode params) {
+ this.cmd = cmd;
+ this.environment = environment;
+ this.msgId = msgId;
+ this.params = params;
+ }
+
+ public FlipperEnvironmentMessageJSON() {}
+
+ @Override
+ public String toString(){
+ return this.cmd + " : " + this.environment + " : " + this.msgId + " : " + this.params.toString();
+ }
+}
diff --git a/src/main/java/hmi/flipper2/environment/IFlipperEnvironment.java b/src/main/java/hmi/flipper2/environment/IFlipperEnvironment.java
new file mode 100644
index 0000000..03c2e26
--- /dev/null
+++ b/src/main/java/hmi/flipper2/environment/IFlipperEnvironment.java
@@ -0,0 +1,20 @@
+package hmi.flipper2.environment;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import java.sql.Connection;
+
+public interface IFlipperEnvironment {
+
+ public void setRequiredEnvironments(IFlipperEnvironment[] envs) throws Exception;
+ public void init(JsonNode params) throws Exception;
+ public void init(JsonNode params, Connection connection) throws Exception;
+ public FlipperEnvironmentMessageJSON onMessage(FlipperEnvironmentMessageJSON fenvmsg) throws Exception;
+
+ public boolean hasMessage();
+ public FlipperEnvironmentMessageJSON getMessage() throws Exception;
+
+ public String getId();
+ public void setId(String id);
+}
+
diff --git a/src/main/java/hmi/flipper2/example/Dynamic.java b/src/main/java/hmi/flipper2/example/Dynamic.java
index 52fe485..751a915 100644
--- a/src/main/java/hmi/flipper2/example/Dynamic.java
+++ b/src/main/java/hmi/flipper2/example/Dynamic.java
@@ -18,61 +18,94 @@
******************************************************************************/
package hmi.flipper2.example;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import hmi.flipper2.environment.BaseFlipperEnvironment;
+import hmi.flipper2.environment.FlipperEnvironmentMessageJSON;
+import hmi.flipper2.environment.IFlipperEnvironment;
+
import java.io.StringReader;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
-public class Dynamic {
+public class Dynamic extends BaseFlipperEnvironment {
private final static boolean verbose = false;
+ private ObjectMapper mapper;
+
private Double base;
public Dynamic() {
if (verbose)
- System.out.println("Dynamic() called");
+ logger.info("Dynamic() called");
this.base = 0.0;
}
+ @Override
+ public FlipperEnvironmentMessageJSON onMessage(FlipperEnvironmentMessageJSON fenvmsg) throws Exception {
+ switch(fenvmsg.cmd){
+ case "Double":
+ Double one = fenvmsg.params.get("content").get("one").asDouble();
+ Double two = fenvmsg.params.get("content").get("two").asDouble();
+ JsonNode res = mapper.createObjectNode().put("f",this.fplus(one,two));
+ enqueueMessage(res,"f",fenvmsg.msgId);
+ break;
+ default:
+ logger.error("No appropriate CMD was given: {}",fenvmsg.cmd);
+ }
+ return null;
+ }
+
+ @Override
+ public void setRequiredEnvironments(IFlipperEnvironment[] envs) throws Exception {
+
+ }
+
+ @Override
+ public void init(JsonNode params) {
+ this.mapper = new ObjectMapper();
+ }
+
public Dynamic(Double base) {
if (verbose)
- System.out.println("Dynamic(Double(" + base + ")) called");
+ logger.info("Dynamic(Double(" + base + ")) called");
this.base = base;
}
public static Boolean alwaysTrue() {
if (verbose)
- System.out.println("Dynamic:method:alwaysTrue(" + "" + ") called.");
+ logger.info("Dynamic:method:alwaysTrue(" + "" + ") called.");
return Boolean.TRUE;
}
public static void f(String s) {
if (verbose)
- System.out.println("Dynamic:static method:f(String(" + s + ")) called.");
+ logger.info("Dynamic:static method:f(String(" + s + ")) called.");
}
public static void f(Double d) {
if (verbose)
- System.out.println("Dynamic:static method:f(Double(" + d + ")) called.");
+ logger.info("Dynamic:static method:f(Double(" + d + ")) called.");
}
public Double fplus(Double dl, Double dr) {
if (verbose)
- System.out.println("Dynamic:static method:f(Double(" + dl + "," + dr + ")) called.");
+ logger.info("Dynamic:static method:f(Double(" + dl + "," + dr + ")) called.");
return base + dl + dr;
}
public Double recur(Double dl, Dynamic dyn) {
if (verbose)
- System.out.println("Dynamic: method:recur(" + dl + ", obj.base=" + dyn.base + ")) called.");
+ logger.info("Dynamic: method:recur(" + dl + ", obj.base=" + dyn.base + ")) called.");
return base + dl;
}
public String fjson(String json) {
if (verbose)
- System.out.println("Dynamic:static method:fjson(json=" + json + ") called.");
+ logger.info("Dynamic:static method:fjson(json=" + json + ") called.");
JsonObject jso = string2json(json);
JsonObject jso_counter = jso.getJsonObject("counter");
JsonValue jso_value = jso_counter.get("value");
diff --git a/src/main/java/hmi/flipper2/example/PersonDbExample.java b/src/main/java/hmi/flipper2/example/PersonDbExample.java
index ee4e7da..cd5d0b9 100644
--- a/src/main/java/hmi/flipper2/example/PersonDbExample.java
+++ b/src/main/java/hmi/flipper2/example/PersonDbExample.java
@@ -36,6 +36,8 @@
import hmi.flipper2.FlipperException;
+import static hmi.flipper2.TemplateController.logger;
+
public class PersonDbExample {
private Connection connection;
@@ -90,7 +92,7 @@ public String getPerson(Integer id) throws FlipperException {
throw new FlipperException("Person with id \"" + id + "\" not found.");
} catch (SQLException e) {
- System.out.println("CAUGHT: " + e);
+ logger.error("CAUGHT: " + e);
throw new FlipperException(e);
}
}
@@ -99,7 +101,7 @@ public void greetingsToMa(String json) {
JsonObject jperson = string2json(json);
String fn = jperson.getString("firstname");
String ln = jperson.getString("lastname");
- System.out.println("!@! Person \"" + fn + " " + ln + "\" sends greetings to his Mother");
+ logger.debug("!@! Person \"" + fn + " " + ln + "\" sends greetings to his Mother");
}
/*
diff --git a/src/main/java/hmi/flipper2/javascript/JsEngine.java b/src/main/java/hmi/flipper2/javascript/JsEngine.java
index 4bb9789..157cde0 100644
--- a/src/main/java/hmi/flipper2/javascript/JsEngine.java
+++ b/src/main/java/hmi/flipper2/javascript/JsEngine.java
@@ -30,6 +30,8 @@
import hmi.flipper2.Config;
import hmi.flipper2.FlipperException;
+import static hmi.flipper2.TemplateController.logger;
+
public class JsEngine {
private ScriptEngineManager mgr;
@@ -43,7 +45,7 @@ public JsEngine(TemplateController tc) throws FlipperException {
protected void js_init(TemplateController tc) throws FlipperException {
this.mgr = new ScriptEngineManager();
- this.engine = mgr.getEngineByName("nashorn");
+ this.engine = mgr.getEngineByName("graal.js");
this.invocable = (Invocable)engine;
this.tc = tc;
}
@@ -62,7 +64,7 @@ public Object eval(String script) throws FlipperException {
try {
if ( Config.debugging && this.tc.dbg != null )
this.tc.dbg.start_JavascriptExec("js", script);
- // System.out.println("XXXXXX->"+script);
+ logger.debug("XXXXXX->"+script);
Object res = engine.eval(script);
if ( Config.debugging && this.tc.dbg != null )
this.tc.dbg.stop_JavascriptExec("js", (res==null)?null:res.toString());
diff --git a/src/main/java/hmi/flipper2/javascript/JsExpression.java b/src/main/java/hmi/flipper2/javascript/JsExpression.java
index 9350c08..9ef4db4 100644
--- a/src/main/java/hmi/flipper2/javascript/JsExpression.java
+++ b/src/main/java/hmi/flipper2/javascript/JsExpression.java
@@ -28,6 +28,8 @@
import hmi.flipper2.Config;
import hmi.flipper2.FlipperException;
+import static hmi.flipper2.TemplateController.logger;
+
public class JsExpression {
private static long fcnt = 10000;
@@ -42,7 +44,7 @@ public JsExpression(JsEngine jse, String args, String expr, String format) throw
this.expr = expr;
this.fid = "_f" + fcnt++;
String fundef = "var " + this.fid + " = function(" + args + ") { " + String.format(format, expr) + "; };";
- // System.out.println("FUNDEF: "+fundef);
+ logger.debug("FUNDEF: "+fundef);
jse.eval(fundef);
}
diff --git a/src/main/java/hmi/flipper2/launcher/FlipperLauncher.java b/src/main/java/hmi/flipper2/launcher/FlipperLauncher.java
index aeabbd0..dd07963 100644
--- a/src/main/java/hmi/flipper2/launcher/FlipperLauncher.java
+++ b/src/main/java/hmi/flipper2/launcher/FlipperLauncher.java
@@ -39,7 +39,7 @@ public static void main(String[] args) {
String flipperPropFile = "flipper.properties";
if(args.length % 2 != 0){
- System.err.println(help);
+ logger.error(help);
System.exit(0);
}
@@ -47,7 +47,7 @@ public static void main(String[] args) {
if(args[i].equals("-config")) {
flipperPropFile = args[i+1];
} else {
- System.err.println("Unknown commandline argument: \""+args[i]+" "+args[i+1]+"\".\n"+help);
+ logger.error("Unknown commandline argument: \""+args[i]+" "+args[i+1]+"\".\n"+help);
System.exit(0);
}
}
diff --git a/src/main/java/hmi/flipper2/launcher/FlipperLauncherThread.java b/src/main/java/hmi/flipper2/launcher/FlipperLauncherThread.java
index 91c56b2..fb44397 100644
--- a/src/main/java/hmi/flipper2/launcher/FlipperLauncherThread.java
+++ b/src/main/java/hmi/flipper2/launcher/FlipperLauncherThread.java
@@ -98,6 +98,10 @@ private void init(Properties ps) {
this.maxSteps = Integer.parseInt(ps.getProperty("maxSteps", "0"));
this.stopIfUnchanged = Boolean.parseBoolean(ps.getProperty("stopIfUnchanged", "False"));
this.showISViewer = Boolean.parseBoolean(ps.getProperty("isViewer", "False"));
+ if(Boolean.parseBoolean(ps.getProperty("nashorn-compat","false"))){
+ logger.warn("Running Flipper in Nashorn Compatibility mode");
+ System.setProperty("polyglot.js.nashorn-compat","true");
+ }
// Database
this.host = ps.getProperty("host", "");
this.database = ps.getProperty("database", "");
diff --git a/src/main/java/hmi/flipper2/postgres/Database.java b/src/main/java/hmi/flipper2/postgres/Database.java
index b739b95..83c0296 100644
--- a/src/main/java/hmi/flipper2/postgres/Database.java
+++ b/src/main/java/hmi/flipper2/postgres/Database.java
@@ -45,7 +45,7 @@ public class Database {
public void commit() throws FlipperException {
try {
- // System.out.println("COMMIT!");
+ logger.debug("COMMIT!");
conn.commit();
} catch (SQLException e) {
throw new FlipperException(e);
@@ -197,7 +197,7 @@ public void removeTemplateFile(TemplateController tc, TemplateFile tf) throws Fl
public void updateTemplateFileIs(TemplateFile tf, String is_value) throws FlipperException {
try {
- // System.out.println("UPDATE TEMPLATE FILE (tf_id="+tf.tfid+"): "+ is_value);
+ logger.debug("UPDATE TEMPLATE FILE (tf_id="+tf.tfid+"): "+ is_value);
String updateTableSQL = "UPDATE flipper_tf SET json_is = to_json(?::json), sync_is = sync_is+1, updated = ? WHERE tfid = ? RETURNING sync_is;";
PreparedStatement preparedStatement = conn.prepareStatement(updateTableSQL);
preparedStatement.setString(1, is_value);
@@ -219,7 +219,7 @@ public void updateTemplateFileIs(TemplateFile tf, String is_value) throws Flippe
public List getTemplateFiles(TemplateController tc) throws FlipperException {
List res = new ArrayList();
- // System.out.println("INCOMPLETE:Database:getTemplateFiles");
+ logger.warn("INCOMPLETE:Database:getTemplateFiles");
try {
String selectSQL = "SELECT tfid,path,xml,json_is#>>'{}' AS json_is,sync_is FROM flipper_tf WHERE cid = ?;";
PreparedStatement preparedStatement = conn.prepareStatement(selectSQL);
diff --git a/src/main/java/hmi/flipper2/sax/SimpleHandler.java b/src/main/java/hmi/flipper2/sax/SimpleHandler.java
index b079426..25dbbd4 100644
--- a/src/main/java/hmi/flipper2/sax/SimpleHandler.java
+++ b/src/main/java/hmi/flipper2/sax/SimpleHandler.java
@@ -25,6 +25,8 @@
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
+import static hmi.flipper2.TemplateController.logger;
+
public class SimpleHandler extends DefaultHandler {
private Vector stack = null;
@@ -91,7 +93,7 @@ private String getParseExceptionInfo(SAXParseException spe) {
}
public void warning(SAXParseException spe) throws SAXException {
- System.out.println("Warning: " + getParseExceptionInfo(spe));
+ logger.warn("Warning: " + getParseExceptionInfo(spe));
}
public void error(SAXParseException spe) throws SAXException {
diff --git a/src/main/java/hmi/flipper2/value/IsJavaValue.java b/src/main/java/hmi/flipper2/value/IsJavaValue.java
index 5455526..52e5046 100644
--- a/src/main/java/hmi/flipper2/value/IsJavaValue.java
+++ b/src/main/java/hmi/flipper2/value/IsJavaValue.java
@@ -27,6 +27,8 @@
import hmi.flipper2.dataflow.DataFlow;
import hmi.flipper2.javascript.JsExpression;
+import static hmi.flipper2.TemplateController.logger;
+
public class IsJavaValue extends JavaValue {
private Is is;
@@ -60,7 +62,7 @@ public Class> objectClass() throws FlipperException {
if (this.vt_type == ValueTransferType.TYPE_JSONSTRING)
return String.class;
else if (this.cl != null ) {
- // System.out.println("DEFCLASS="+cl.getName());
+ logger.debug("DEFCLASS="+cl.getName());
return this.cl;
} else
throw new RuntimeException("Should define class for is="+path+", is_type: Object. Dynamic calls implemented in future");
diff --git a/src/main/resources/example/Dynamic.xml b/src/main/resources/example/Dynamic.xml
new file mode 100644
index 0000000..5f0b65f
--- /dev/null
+++ b/src/main/resources/example/Dynamic.xml
@@ -0,0 +1,133 @@
+
+
+
+ {
+ "dynamic":{
+ "initialized": false,
+ "requestQueue" : [],
+ "response" : {},
+ "messages" : {}
+ },
+ "counter" : 0
+ }
+
+
+
+
+ 0){
+ //Compare the message received to messages in the requestQueue
+ for(i = 0; i < is.components.dynamic.requestQueue.length; i++){
+ if(is.components.dynamic.requestQueue[i].response.requestId === res.msgId){
+ is.components.dynamic.messages = res.params;
+ //is.components.counter = is.components.dynamic.messages.f;
+ element = i;
+ }
+ }
+ }
+ // Remove the message from the queue, once it is processed.
+ is.components.dynamic.requestQueue.splice(element,1);
+ }
+
+ // Whenever we want to send something from Flipper to Java, we push it to the requestQueue.
+ var updateDYN = function(message){
+ is.components.dynamic.requestQueue.push({content : message});
+ return message;
+ }
+
+ // Once you have added the requests, you can use this method to send requests to the environment
+ var MakeRequests = function(type) {
+ for (var i=0; i < is.components.dynamic.requestQueue.length; i++) {
+ if (is.components.dynamic.requestQueue[i].response != null) continue;
+ var requestId = ENV.queueMessage("dynamic", type, is.components.dynamic.requestQueue[i]);
+ is.components.dynamic.requestQueue[i].response = {
+ requestId: requestId
+ };
+ }
+ }
+
+ //Register your listeners and request handlers here.
+ function Init() {
+ ENV.register("f", handleDYNResponse);
+ return true;
+ }
+
+ return {
+ Init: Init,
+ MakeRequests: MakeRequests,
+ updateDYN: updateDYN
+ };
+
+ })();
+ ]]>
+
+
+
+
+
+
+
+
+
+ DYN.Init();
+
+
+
+
+
+
+ = 0]]>
+
+
+ DYN.updateDYN({one:3.0,two:is.components.counter})
+ DYN.MakeRequests("Double")
+
+
+
+
+
+
+ 0 ]]>
+
+
+ prnt(is.components.dynamic.messages)
+ is.components.dynamic.messages.f
+ {}
+
+
+
+
diff --git a/src/main/resources/example/Environment.xml b/src/main/resources/example/Environment.xml
new file mode 100644
index 0000000..24ad994
--- /dev/null
+++ b/src/main/resources/example/Environment.xml
@@ -0,0 +1,257 @@
+
+
+
+
+ {
+ "temp": { "newenvmsgs":[], "newenvresponses":[], "newenvoutmsgs": [] },
+ "initialized":false,
+ "initnoerror":false,
+ "environmentSpec": {
+ "environments": [
+ {
+ "id" : "dynamic", "loader":"hmi.flipper2.example.Dynamic", "requiredloaders":[]
+ }
+ ]
+ }
+ }
+
+
+ "+JSON.stringify(msgs[i]));
+ publishMsg(msgs[i].cmd, msgs[i]);
+ }
+ return [];
+ }
+
+ function handleEnvironmentResponses(msgs) {
+ for (var i = 0; i < msgs.length; i++) {
+ //print("res > "+JSON.stringify(msgs[i]));
+ publishMsg(msgs[i].cmd, msgs[i]);
+ }
+ return [];
+ }
+
+ function haveMessagesQueued() {
+ return messageQueue.length > 0;
+ }
+
+ function queueMessage(environment, cmd, params) {
+ var msgId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+ messageQueue.push({
+ environment: environment,
+ cmd: cmd,
+ msgId: msgId,
+ params: params
+ });
+ return msgId;
+ }
+
+ function queueResponse(respondTo, params) {
+ messageQueue.push({
+ environment: respondTo.environment,
+ cmd: respondTo.cmd,
+ msgId: respondTo.msgId,
+ params: params
+ });
+ return respondTo.msgId;
+ }
+
+ function getEntireMessageQueue() {
+ var res = messageQueue;
+ messageQueue = [];
+ return res;
+ }
+
+ return {
+ register: register,
+ handleEnvironmentMessages: handleEnvironmentMessages,
+ queueMessage: queueMessage,
+ handleEnvironmentResponses: handleEnvironmentResponses,
+ haveMessagesQueued: haveMessagesQueued,
+ getEntireMessageQueue: getEntireMessageQueue,
+ queueResponse: queueResponse,
+ isInitialized: function() {
+ return is.env.initialized && is.env.initnoerror;
+ }
+ };
+})();
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/example/Flipper2Count.xml b/src/main/resources/example/Flipper2Count.xml
index 3eff73b..82fe105 100644
--- a/src/main/resources/example/Flipper2Count.xml
+++ b/src/main/resources/example/Flipper2Count.xml
@@ -2,7 +2,7 @@
{
- "value" : 1
+ "value" : 1.0
}
diff --git a/src/main/resources/flipper.properties b/src/main/resources/flipper.properties
index cdcc16e..b62476f 100644
--- a/src/main/resources/flipper.properties
+++ b/src/main/resources/flipper.properties
@@ -1,21 +1,23 @@
# name for TemplateController
-name: flipperis
+name=flipperis
# comma seperated list of external lists
-jslibs: jslibs/underscore-min.js
+jslibs=jslibs/underscore-min.js
# comma seperated list of template paths
-templates: example/Underscore.xml
+templates=example/Flipper2Count.xml, example/Environment.xml, example/Dynamic.xml
#evaluate template every 1000/evalFrequency milliseconds
-evalFrequency: 1
+evalFrequency=1
#n=0:don't stop, n=1+: stop after n times checking templates
-maxSteps: 0
+maxSteps=0
#True|False
-stopIfUnchanged: False
+stopIfUnchanged=False
#ALL,NONE,ONLY_CHANGED
-autoReloadTemplates: ONLY_CHANGED
+autoReloadTemplates=ONLY_CHANGED
#Data flow analysis
-analyze: False
+analyze=True
#Show GUI
-isViewer: False
+isViewer=False
+#Nashorn compatible javascript default: false
+nashorn-compat=False
#host: 127.0.0.1
#database: flipperis