Commit ca7ca039 authored by maquil's avatar maquil

Merge branch 'dev-nico' of https://git.list.lu/nui/TULIP-CPS.git into dev-nico

parents 6cb56c6b 13665e57
......@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip-cps</artifactId>
<version>1.3.1</version>
<version>1.4.0</version>
<name>TULIP Complex Problem Solving</name>
<licenses>
......@@ -59,6 +59,27 @@
<artifactId>jython-standalone</artifactId>
<version>2.7.1b3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.23</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8</version>
<scope>runtime</scope>
</dependency>
</dependencies>
......
......@@ -27,9 +27,10 @@ import lu.list.itis.dkd.tui.cps.variable.Variable;
import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedHashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
......@@ -49,7 +50,7 @@ public class Equation {
private Executor scriptExecutor;
private String script;
private static Logger LOGGER = Logger.getLogger(Equation.class.getSimpleName());
private static Logger LOGGER = LoggerFactory.getLogger(Equation.class.getSimpleName());
/**
* Constructor
......@@ -103,7 +104,7 @@ public class Equation {
scriptExecutor.eval(this.script);
} catch (Exception exception) {
LOGGER.log(Level.SEVERE, "Error while evaluating script " + this.script, exception); //$NON-NLS-1$
LOGGER.error("Error while evaluating script {}", this.script, exception); //$NON-NLS-1$
}
dependentVariables = mapping.getDependentVariables();
......@@ -111,18 +112,18 @@ public class Equation {
try {
variable = scriptExecutor.get(variable);
} catch (Exception exception) {
LOGGER.log(Level.SEVERE, "Error while retrieving variable " + variable.getName(), exception); //$NON-NLS-1$
LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$
}
}
evaluationErrors = scriptExecutor.getExecutionErrors();
if (evaluationErrors.length() > 0) {
LOGGER.log(Level.WARNING, "Error while evaluating equation :" + evaluationErrors); //$NON-NLS-1$
LOGGER.log(Level.WARNING, "Script =" + this.script); //$NON-NLS-1$
LOGGER.warn("Error while evaluating equation : {}", evaluationErrors); //$NON-NLS-1$
LOGGER.warn("Script = {}", this.script); //$NON-NLS-1$
LinkedHashSet<Variable> independentVariables = mapping.getIndependentVariables();
for (Variable variable : independentVariables) {
LOGGER.log(Level.INFO, variable.getName() + " = " + variable.getValue()); //$NON-NLS-1$
LOGGER.trace("{} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
}
......
......@@ -3,15 +3,17 @@ package lu.list.itis.dkd.tui.cps.system.executor;
import lu.list.itis.dkd.tui.cps.system.Import;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.CharArrayWriter;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
abstract public class Executor {
protected CharArrayWriter executionErrors;
private static Logger LOGGER = Logger.getLogger(Executor.class.getSimpleName());
private static Logger LOGGER = LoggerFactory.getLogger(Executor.class.getSimpleName());
public Executor() {
executionErrors = new CharArrayWriter();
......@@ -32,7 +34,7 @@ abstract public class Executor {
@SuppressWarnings("unused")
public void resolve(List<Import> imports) {
LOGGER.warning("Imports not supported by Executor!"); //$NON-NLS-1$
LOGGER.warn("Imports not supported by Executor!"); //$NON-NLS-1$
}
abstract public void set(Variable variable);
......
......@@ -2,8 +2,10 @@ package lu.list.itis.dkd.tui.cps.system.executor;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
......@@ -13,7 +15,7 @@ public class JavascriptExecutor extends Executor {
private ScriptEngine engine;
private Object result;
private static Logger LOGGER = Logger.getLogger(JavascriptExecutor.class.getSimpleName());
private static Logger LOGGER = LoggerFactory.getLogger(JavascriptExecutor.class.getSimpleName());
public JavascriptExecutor() {
engine = new ScriptEngineManager().getEngineByName("js"); //$NON-NLS-1$
......@@ -28,14 +30,24 @@ public class JavascriptExecutor extends Executor {
@Override
public void set(Variable variable) {
engine.put(variable.getName(), variable.getValue());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
@Override
public boolean eval(String script) {
try {
long elapsed = System.currentTimeMillis();
result = engine.eval(script);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
}
} catch (ScriptException exception) {
this.executionErrors.append(exception.toString());
LOGGER.warn("Failed to eval script => {}", script); //$NON-NLS-1$
LOGGER.warn("Caused by...", exception); //$NON-NLS-1$
return false;
}
return true;
......@@ -44,6 +56,9 @@ public class JavascriptExecutor extends Executor {
@Override
public Variable get(Variable variable) {
variable.setValue(result);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}", variable.getName(), result); //$NON-NLS-1$
}
return variable;
}
}
......@@ -2,6 +2,9 @@ package lu.list.itis.dkd.tui.cps.system.executor;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Properties;
......@@ -16,14 +19,25 @@ public class OctaveExecutor extends Executor {
private static final String SCRIPT_ENGINE_EXECUTABLE = "octave.executable"; //$NON-NLS-1$
private static final String SCRIPT_ENGINE_WORKING_DIR = "octave.workingDir"; //$NON-NLS-1$
// private static Logger LOGGER = Logger.getLogger(OctaveExecutor.class.getSimpleName());
private static final String DEFAULT_EXECUTABLE = "/opt/local/bin/octave"; //$NON-NLS-1$
private static final String DEFAULT_WORKING_DIR = "octave"; //$NON-NLS-1$
private static Logger LOGGER = LoggerFactory.getLogger(OctaveExecutor.class.getSimpleName());
public OctaveExecutor(Properties properties) {
super(properties);
OctaveEngineFactory engineFactory = new OctaveEngineFactory();
engineFactory.setOctaveProgram(new File(properties.getProperty(SCRIPT_ENGINE_EXECUTABLE, "/opt/local/bin/octave"))); //$NON-NLS-1$
engineFactory.setWorkingDir(new File(properties.getProperty(SCRIPT_ENGINE_WORKING_DIR, "octave"))); //$NON-NLS-1$
String executable = properties.getProperty(SCRIPT_ENGINE_EXECUTABLE, DEFAULT_EXECUTABLE);
String workingDir = properties.getProperty(SCRIPT_ENGINE_WORKING_DIR, DEFAULT_WORKING_DIR);
engineFactory.setOctaveProgram(new File(executable));
engineFactory.setWorkingDir(new File(workingDir));
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Octave Executable : {}", executable); //$NON-NLS-1$
LOGGER.info("Octave Working Dir : {}", workingDir); //$NON-NLS-1$
}
engine = engineFactory.getScriptEngine();
engine.setErrorWriter(this.executionErrors);
......@@ -33,11 +47,19 @@ public class OctaveExecutor extends Executor {
public void set(Variable variable) {
Double numericValue = Double.valueOf(variable.getValue().toString());
engine.put(variable.getName(), Octave.scalar(numericValue));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
@Override
public boolean eval(String script) {
long elapsed = System.currentTimeMillis();
engine.eval(script);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
}
return true;
}
......@@ -45,6 +67,10 @@ public class OctaveExecutor extends Executor {
public Variable get(Variable variable) {
OctaveDouble result = engine.get(OctaveDouble.class, variable.getName());
variable.setValue(result.get(1));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}", variable.getName(), result.get(1)); //$NON-NLS-1$
}
return variable;
}
......
......@@ -7,11 +7,11 @@ import org.python.core.PyFloat;
import org.python.core.PyObject;
import org.python.core.PyTuple;
import org.python.util.PythonInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
......@@ -22,7 +22,7 @@ public class PythonExecutor extends Executor {
private static final Pattern TUPLE_PATTERN = Pattern.compile("^([a-z0-9_]+)\\.([a-z0-9_]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static Logger LOGGER = Logger.getLogger(PythonExecutor.class.getSimpleName());
private static Logger LOGGER = LoggerFactory.getLogger(PythonExecutor.class.getSimpleName());
public PythonExecutor(Properties properties) {
super(properties);
......@@ -41,8 +41,7 @@ public class PythonExecutor extends Executor {
StringBuilder importBuilder = new StringBuilder("from "); //$NON-NLS-1$
importBuilder.append(declaration.getFrom()).append(" import ").append(declaration.getFunction()); //$NON-NLS-1$
engine.exec(importBuilder.toString());
LOGGER.log(Level.INFO, importBuilder.toString());
LOGGER.info(importBuilder.toString());
}
}
......@@ -50,11 +49,19 @@ public class PythonExecutor extends Executor {
public void set(Variable variable) {
Double numericValue = Double.valueOf(variable.getValue().toString());
engine.set(variable.getName(), new PyFloat(numericValue));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
@Override
public boolean eval(String script) {
long elapsed = System.currentTimeMillis();
engine.exec(script);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
}
return true;
}
......@@ -67,9 +74,16 @@ public class PythonExecutor extends Executor {
if (tupleMatcher.matches()) {
PyTuple tuple = (PyTuple) engine.get(tupleMatcher.group(1));
result = tuple.__getattr__(tupleMatcher.group(2));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}.{} = {}", variable.getName(), tupleMatcher.group(1), tupleMatcher.group(2), result); //$NON-NLS-1$
}
}
} else {
result = engine.get(variable.getName());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}", variable.getName(), result); //$NON-NLS-1$
}
}
variable.setValue((result != null) ? result.__tojava__(Double.class) : null);
return variable;
......
......@@ -32,12 +32,13 @@ public class Externalization extends NLS {
private static final String BUNDLE_NAME = "lu.list.itis.dkd.tui.cps.utility.externalization";
public static String EXECUTOR_CLASS;
public static String VARIABLE_CLASS;
public static String NUMERIC_VARIABLE_CLASS;
public static String LOGIC_VARIABLE_CLASS;
public static String EQUATION_ELEMENT;
public static String EQUATIONS_ELEMENT;
public static String INVOKE_ELEMENT;
public static String NAME_ELEMENT;
public static String NAME_ATTRIBUTE;
public static String OUTPUT_ELEMENT;
public static String OUTPUTS_ELEMENT;
public static String PARAMETER_ELEMENT;
......@@ -52,8 +53,15 @@ public class Externalization extends NLS {
public static String FROM_ATTRIBUTE;
public static String IMPORTS_ELEMENT;
public static String SYSTEM_ELEMENT;
public static String TYPE_ATTRIBUTE;
public static String UNIT_ATTRIBUTE;
public static String UNIT_ELEMENT;
public static String MINIMUM_ATTRIBUTE;
public static String MAXIMUM_ATTRIBUTE;
public static String SCALE_ATTRIBUTE;
public static String DECIMALS_ATTRIBUTE;
public static final String LOGIC_TYPE = "logic";
public static final String NUMERIC_TYPE = "numeric";
static {
// initialize resource bundle
......
EXECUTOR_CLASS=executor.class
VARIABLE_CLASS=variable.class
EQUATION_ELEMENT=equation
NUMERIC_VARIABLE_CLASS=numeric.variable.class
LOGIC_VARIABLE_CLASS=logic.variable.class
EQUATIONS_ELEMENT=equations
EQUATION_ELEMENT=equation
INVOKE_ELEMENT=invoke
NAME_ELEMENT=name
OUTPUT_ELEMENT=output
NAME_ATTRIBUTE=name
OUTPUTS_ELEMENT=outputs
OUTPUT_ELEMENT=output
PARAMETER_ELEMENT=parameter
TYPE_ATTRIBUTE=type
INITIAL_ATTRIBUTE=initial
MINIMUM_ATTRIBUTE=minimum
MAXIMUM_ATTRIBUTE=maximum
SCALE_ATTRIBUTE=scale
DECIMALS_ATTRIBUTE=decimals
PARAMETERS_ELEMENT=parameters
PERIODIC_ATTRIBUTE=periodic
RESULT_ELEMENT=result
EQUATE_ATTRIBUTE=equate
RESULTS_ELEMENT=results
IMPORTS_ELEMENT=imports
IMPORT_ELEMENT=import
FUNCTION_ATTRIBUTE=function
FROM_ATTRIBUTE=from
IMPORTS_ELEMENT=imports
SYSTEM_ELEMENT=system
UNIT_ATTRIBUTE=unit
UNIT_ELEMENT=unit
\ No newline at end of file
UNIT_ATTRIBUTE=unit
\ No newline at end of file
......@@ -22,6 +22,7 @@ package lu.list.itis.dkd.tui.cps.variable;
import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import java.util.Vector;
......@@ -39,7 +40,7 @@ public class BooleanVariable extends Variable {
* @param value
*/
public BooleanVariable(String name, boolean value) {
super(name, "boolean"); //$NON-NLS-1$
super(Externalization.LOGIC_TYPE, name, "boolean"); //$NON-NLS-1$
this.value = value;
}
......@@ -56,7 +57,7 @@ public class BooleanVariable extends Variable {
if (value instanceof Boolean) {
this.value = (Boolean) value;
} else {
this.value = Boolean.parseBoolean(value.toString());
this.value = (Boolean) valueFromString(value.toString());
}
for (InputChangeListener listener : listeners) {
......@@ -71,4 +72,10 @@ public class BooleanVariable extends Variable {
variable.listeners = new Vector<>(listeners);
return variable;
}
/** {@inheritDoc} */
@Override
public Object valueFromString(String stringValue) {
return Boolean.parseBoolean(stringValue);
}
}
\ No newline at end of file
......@@ -24,13 +24,14 @@ import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Class implementing numerical variables as handled by the {@link System}.
......@@ -38,12 +39,19 @@ import java.util.logging.Logger;
* @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0
* @version 1.3.0
* @param <T>
*/
@NonNullByDefault
public class NumericalVariable extends Variable {
protected double value;
protected double minValue;
protected double maxValue;
protected double scale;
private DecimalFormat format;
private static final Logger logger = LoggerFactory.getLogger(NumericalVariable.class.getSimpleName());
/**
* Constructor resorting to the super constructor to initialise the name and unit and locally
* initialising the numerical value.
......@@ -55,13 +63,17 @@ public class NumericalVariable extends Variable {
* @param value
* The value held by the variable.
*/
public NumericalVariable(String name, String unit, double value) {
super(name, unit);
public NumericalVariable(String name, String unit, Double value) {
super(Externalization.NUMERIC_TYPE, name, unit);
this.value = value;
format = new DecimalFormat();
format.setDecimalSeparatorAlwaysShown(false);
format.setGroupingUsed(false);
minValue = Double.MIN_VALUE;
maxValue = Double.MAX_VALUE;
scale = 1;
}
/**
......@@ -73,7 +85,7 @@ public class NumericalVariable extends Variable {
* necessary information to initialize the variable.
*/
public NumericalVariable(Element rootElement) {
super(rootElement.getChildText("name"), rootElement.getChildText("unit")); //$NON-NLS-1$ //$NON-NLS-2$
super(Externalization.NUMERIC_TYPE, rootElement.getChildText("name"), rootElement.getChildText("unit")); //$NON-NLS-1$ //$NON-NLS-2$
this.value = Double.parseDouble(rootElement.getChildText("value")); //$NON-NLS-1$
format = new DecimalFormat();
......@@ -82,12 +94,6 @@ public class NumericalVariable extends Variable {
}
/** {@inheritDoc} */
@Override
public Double getValue() {
return value;
}
/**
* {@inheritDoc}<br>
* <br>
......@@ -144,19 +150,91 @@ public class NumericalVariable extends Variable {
/** {@inheritDoc} */
@Override
public void setValue(Object value) {
try {
this.value = Double.parseDouble(value.toString());
Double newValue;
newValue = (Double) this.valueFromString(value.toString());
if (newValue < this.minValue)
this.value = this.minValue;
else if (newValue > this.maxValue)
this.value = this.maxValue;
else
this.value = newValue;
for (InputChangeListener listener : listeners) {
listener.inputChanged(new InputEvent(this));
}
} catch (NumberFormatException e) {
Logger.getLogger(NumericalVariable.class.getSimpleName()).log(Level.SEVERE, "The provided value (" + value.toString() + ") does not match " //$NON-NLS-1$ //$NON-NLS-2$
+ "the value stored by this variable instance.", e); //$NON-NLS-1$
throw e;
InputEvent event = new InputEvent(this);
for (InputChangeListener listener : listeners) {
// listener.inputChanged(new InputEvent(this));
listener.inputChanged(event);
}
// EventLogger.getInstance().addNumericalVariableInfo(this.name, format.format(value),
// unit);
}
/** {@inheritDoc} */
@Override
public Object getValue() {
return this.value;
}
/**
*
* @param value
* specifies the new minimum value for this variable
*/
public void setMinValue(double value) {
this.minValue = value;
}
/**
*
* @return the minimum value defined for this variable. If not previously set, the minimum value
* will be Double.MIN_VALUE
*/
public double getMinValue() {
return this.minValue;
}
/**
*
* @param value
* specifies the new maximum value for this variable
*/
public void setMaxValue(double value) {
this.maxValue = value;
}
/**
*
* @return the maximum value defined for this variable. If not previously set, the minimum value
* will be Double.MAX_VALUE
*/
public double getMaxValue() {
return this.maxValue;
}
/**
*
* @param scale
* specifies the display scale for this variable.
*/
public void setScale(double scale) {
this.scale = scale;
}
/**
*
* @return the scale to be used when displaying the value of this variable.
*/
public double getScale() {
return this.scale;
}
/**
*
* @param decimals
* specifies the number of decimals when displaying this variable.
*/
public void setNumberOfDecimals(int decimals) {
this.format.setMaximumFractionDigits(decimals);
}
/** {@inheritDoc} */
......@@ -164,7 +242,23 @@ public class NumericalVariable extends Variable {
public NumericalVariable clone() {
NumericalVariable variable = new NumericalVariable(name, unit, value);
variable.format = format;
variable.minValue = minValue;
variable.maxValue = maxValue;
variable.scale = scale;
variable.listeners = new Vector<>(listeners);
return variable;
}
/** {@inheritDoc} */
@Override
public Object valueFromString(String stringValue) {
Double newValue = Double.valueOf(0);
try {
newValue = Double.parseDouble(stringValue);
} catch (NumberFormatException e) {
logger.error("The provided value ({}) does not match the format stored by this variable instance.", stringValue, e); //$NON-NLS-1$
throw e;
}
return newValue;
}
}
\ No newline at end of file
......@@ -32,9 +32,12 @@ import java.util.Vector;
* @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0
* @version 1.3.0
* @param <T>
*/
@NonNullByDefault
public abstract class Variable implements Cloneable {
/** The data type of the variable. */
protected String type;
/** The name of the variable. */
protected String name;
/** The unit the variable is given in. */
......@@ -54,12 +57,22 @@ public abstract class Variable implements Cloneable {
* @param unit
* The unit the variable is given in.
*/
public Variable(String name, String unit) {
public Variable(String type, String name, String unit) {
this.type = type;
this.name = name;
this.unit = unit;
listeners = new Vector<>();
}
/**
* Simple getter method for unit.
*
* @return The value of unit.
*/
public String getType() {
return type;
}
/**
* Simple getter method for name.
*
......@@ -136,7 +149,9 @@ public abstract class Variable implements Cloneable {
if (object instanceof Variable) {
Variable variable = (Variable) object;
if (name.equals(variable.getName()) && unit.equals(variable.getUnit())) {
if (type.equals(variable.getType()) &&
name.equals(variable.getName()) &&
unit.equals(variable.getUnit())) {
return true;
}
}
......@@ -157,4 +172,14 @@ public abstract class Variable implements Cloneable {
/** {@inheritDoc} */
@Override
public abstract Variable clone();
/**
*
* @param stringValue
* specifies a stringified version of the value to be converted
* @return
*/
public abstract Object valueFromString(String stringValue);
}
\ No newline at end of file
......@@ -41,7 +41,7 @@ import org.jdom2.Element;
* @version 1.3.0
*/
@NonNullByDefault
public class TangibleNumericalVariable extends NumericalVariable implements ContextEventListener, InformationProvider<String> {
public class TangibleNumericalVariable extends NumericalVariable implements ContextEventListener, InformationProvider<Double> {
/**
* Constructor resorting to the super constructor to initialise the name and unit and locally
* initialising the numerical value.
......@@ -80,7 +80,7 @@ public class TangibleNumericalVariable extends NumericalVariable implements Cont
/** This method is not supported and will always return the general, position-agnostic value. */
@Override
public String getInformation(@Nullable Point position) {