...
 
Commits (48)
*.metadata
*.classpath
CPS/target
\ No newline at end of file
CPS/target
/.DS_Store
......@@ -5,6 +5,11 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
......@@ -19,5 +24,6 @@
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/${PROJECT_DIR_NAME}/python</path>
</pydev_pathproperty>
</pydev_project>
ABOVE_ELEMENT=above
BELOW_ELEMENT=below
BLINK_ON_OUT_OF_RANGE_NODE=blinkOnOutOfRange
CAPPED_DISPLAY_NODE=cappedDisplay
ITEMS_VARIABLE_NODE=itemsVariable
HTML_TEMPLATE_NODE=htmlTemplate
LABEL_NODE=label
LOWER_BOUND_RADIUS_NODE=lowerBoundRadius
LOWER_BOUND_VARIABLE_NODE=lowerBoundVariable
LOWER_STOP_ANGLE_NODE=lowerStopAngle
MAXIMUM_VALUE_NODE=maximumValue
MINIMUM_VALUE_NODE=minimumValue
MODIFY_VALUE_ON_ROTATION_NODE=modifyValueOnRotation
RADIAL_LAYOUT_NODE=radialLayout
REFERENCE_NODE=reference
RELATIVE_NODE=relative
SELECTED_ITEMS_VARIABLE_NODE=selectedItemsVariable
SELECTED_RADIUS_NODE=selectedRadius
STEP_SIZE_NODE=stepSize
UPPER_BOUND_RADIUS_NODE=upperBoundRadius
UPPER_BOUND_VARIABLE_NODE=upperBoundVariable
UPPER_STOP_ANGLE_NODE=upperStopAngle
VARIABLE_NODE=variable
VARIABLES_NODE=variables
\ No newline at end of file
......@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip-cps</artifactId>
<version>1.4.0</version>
<version>1.5.0</version>
<name>TULIP Complex Problem Solving</name>
<licenses>
......@@ -47,7 +47,7 @@
<dependency>
<groupId>lu.list.itis.dkd.tui</groupId>
<artifactId>tulip</artifactId>
<version>2.4.0</version>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>maven2.dk.ange</groupId>
......@@ -67,12 +67,12 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8</version>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8</version>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
......@@ -80,16 +80,27 @@
<version>2.8</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>Kenai</id>
<name>Kenai</name>
<url>https://svn.kenai.com/svn/javaoctave~maven-repository</url>
</repository>
</repositories>
<repository>
<id>LIST</id>
<name>Artifacts</name>
<url>https://artefacts.list.lu/libs-release-local</url>
</repository>
</repositories>
</project>
\ No newline at end of file
/Spatial$py.class
'''
Created on Aug 16, 2017
@author: mack
'''
def AddPoints (A, B):
C = {}
C['x'] = A['x'] + B['x']
C['y'] = A['y'] + B['y']
C['a'] = A['a'] + B['a']
return C
\ No newline at end of file
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.bootstrapping;
import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.system.VariableBased;
import lu.list.itis.dkd.tui.cps.variable.NumericalVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.ColorFactory;
import lu.list.itis.dkd.tui.utility.Templating;
import lu.list.itis.dkd.tui.widget.BaseWidget;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class DisplayWidgetBootstrapper implements BootstrapCallback {
private List<Variable<?>> variables;
private Iterator<Variable<?>> variableIterator;
private Variable<?> variable;
private List<Color> variableColours;
private Integer index;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static final Logger LOGGER = LoggerFactory.getLogger(DisplayWidgetBootstrapper.class.getName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public DisplayWidgetBootstrapper(List<Variable<?>> variables) {
this.variables = variables;
this.variableColours = ColorFactory.makeRainbowColours(variables.size());
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
public List<BaseWidget> buildWidgetsFromVariables(Element template, Integer widgetId, BootstrapContext context, BootstrapCallback callback) throws BuildException {
List<BaseWidget> widgets = null;
Map<String, Variable<?>> systemVariables = new HashMap<>();
index = 0;
context.setProperty(Templating.HANDLE_ID_PROPERTY, widgetId);
context.setProperty(Templating.NUMBER_OF_VARIABLES_PROPERTY, variables.size());
for (Variable<?> systemVariable : variables) {
systemVariables.put(systemVariable.getName(), systemVariable);
}
variableIterator = variables.iterator();
if (variableIterator.hasNext()) {
this.variable = variableIterator.next();
widgets = TangibleObjectBootstrapper.buildWidgetFromTemplate(template, context, this);
for (BaseWidget widget : widgets) {
List<Variable<?>> connected;
if (widget.getClass().isAssignableFrom(VariableBased.class)) {
VariableBased display = (VariableBased) widget;
connected = display.connectWithSystemVariables(systemVariables);
if (widget.getClass().isAssignableFrom(InputChangeListener.class)) {
InputChangeListener listener = (InputChangeListener) widget;
for (Variable<?> connectedVariable : connected)
connectedVariable.addListener(listener);
}
}
}
} else {
LOGGER.warn("Encountered a Widget without any variables. Won't build Widget! ID of offending Widget is {}", widgetId); //$NON-NLS-1$
}
return widgets;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext preInstantiation(Element node, BootstrapContext context) {
context.setProperty(Templating.VARIABLE_NAME_PROPERTY, variable.getName());
context.setProperty(Templating.VARIABLE_DISPLAY_NAME_PROPERTY, variable.getDisplayName());
context.setProperty(Templating.VARIABLE_UNIT_PROPERTY, variable.getUnit());
if (variable instanceof NumericalVariable) {
NumericalVariable numerical = (NumericalVariable) variable;
context.setProperty(Templating.VARIABLE_MINVALUE_PROPERTY, numerical.getMinValue());
context.setProperty(Templating.VARIABLE_MAXVALUE_PROPERTY, numerical.getMaxValue());
context.setProperty(Templating.VARIABLE_SCALE_PROPERTY, numerical.getScale());
}
Color colour = variableColours.get(index);
context.setProperty(Templating.VARIABLE_COLOUR_PROPERTY, colour.getRGB());
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext postInstantiation(Element node, BootstrapContext context) {
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext next(BootstrapContext context) {
if (variableIterator.hasNext()) {
this.variable = variableIterator.next();
this.index++;
}
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext reset(BootstrapContext context) {
this.index = 0;
variableIterator = variables.iterator();
if (variableIterator.hasNext()) {
this.variable = variableIterator.next();
}
return context;
}
// ---------------------------------------------------------------------------
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.bootstrapping;
import lu.list.itis.dkd.tui.cps.utility.EquationSystemBundle;
import lu.list.itis.dkd.tui.cps.variable.BooleanVariable;
import lu.list.itis.dkd.tui.cps.variable.NumericalVariable;
import lu.list.itis.dkd.tui.cps.variable.TextVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.cps.variable.VectorVariable;
import lu.list.itis.dkd.tui.exception.BuildException;
import org.jdom2.Element;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public class VariableBootstrapper {
public static Variable<?> buildVariableFromElement(Element variableNode, BootstrapContext context, BootstrapCallback callback) throws BuildException {
Variable<?> variable = null;
if (variableNode == null)
return null;
String name = BootstrappingUtils.getContentAsString(variableNode, EquationSystemBundle.NAME_ATTRIBUTE, BootstrappingUtils.MANDATORY, null, context);
String type = BootstrappingUtils.getContentAsString(variableNode, EquationSystemBundle.TYPE_NODE, BootstrappingUtils.MANDATORY, null, context);
switch (type) {
case EquationSystemBundle.NUMERIC_TYPE:
String unit = BootstrappingUtils.getContentAsString(variableNode, EquationSystemBundle.UNIT_ATTRIBUTE, BootstrappingUtils.OPTIONAL, EquationSystemBundle.EMPTY_STRING, context);
double minValue = BootstrappingUtils.getContentAsDouble(variableNode, EquationSystemBundle.MINIMUM_ATTRIBUTE, BootstrappingUtils.OPTIONAL, -Double.MAX_VALUE, context);
double maxValue = BootstrappingUtils.getContentAsDouble(variableNode, EquationSystemBundle.MAXIMUM_ATTRIBUTE, BootstrappingUtils.OPTIONAL, Double.MAX_VALUE, context);
double scale = BootstrappingUtils.getContentAsDouble(variableNode, EquationSystemBundle.SCALE_ATTRIBUTE, BootstrappingUtils.OPTIONAL, 1.0, context);
double numericValue = BootstrappingUtils.getContentAsDouble(variableNode, EquationSystemBundle.INITIAL_ATTRIBUTE, BootstrappingUtils.OPTIONAL, 0.0, context);
NumericalVariable numerical = new NumericalVariable(name, unit, numericValue);
numerical.setMinValue(minValue);
numerical.setMaxValue(maxValue);
numerical.setScale(scale);
variable = numerical;
break;
case EquationSystemBundle.VECTOR_TYPE:
unit = BootstrappingUtils.getContentAsString(variableNode, EquationSystemBundle.UNIT_ATTRIBUTE, BootstrappingUtils.OPTIONAL, EquationSystemBundle.EMPTY_STRING, context);
VectorVariable<?> vectorVariable = new VectorVariable<>(name, unit);
variable = vectorVariable;
break;
case EquationSystemBundle.LOGIC_TYPE:
boolean booleanValue = BootstrappingUtils.getContentAsBoolean(variableNode, EquationSystemBundle.INITIAL_ATTRIBUTE, BootstrappingUtils.OPTIONAL, false, context);
BooleanVariable booleanVariable = new BooleanVariable(name, booleanValue);
variable = booleanVariable;
break;
case EquationSystemBundle.TEXT_TYPE:
String textValue = BootstrappingUtils.getContentAsString(variableNode, EquationSystemBundle.INITIAL_ATTRIBUTE, BootstrappingUtils.OPTIONAL, EquationSystemBundle.EMPTY_STRING, context);
TextVariable textVariable = new TextVariable(name, textValue);
variable = textVariable;
break;
default:
throw new BuildException("Don't know how to build a Variable of type " + type); //$NON-NLS-1$
}
return variable;
}
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.bootstrapping;
import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.system.VariableBased;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.cps.variable.VectorVariable;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.ColorFactory;
import lu.list.itis.dkd.tui.utility.Templating;
import lu.list.itis.dkd.tui.widget.BaseWidget;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Nico Mack [nico.mack@list.lu]
* @since 1.5
* @version 1.5.0
*/
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
public class VectorBasedBootstrapper implements BootstrapCallback {
private List<VectorVariable<?>> variables;
private List<Color> indexColours;
private Integer index;
private Integer size;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static final Logger LOGGER = LoggerFactory.getLogger(VectorBasedBootstrapper.class.getName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s) *
// ***************************************************************************
// ---------------------------------------------------------------------------
public VectorBasedBootstrapper(List<VectorVariable<?>> variables) {
size = -1;
this.variables = variables;
for (VectorVariable<?> variable : variables) {
if (size < 0)
size = variable.size();
if (variable.size() != size) {
LOGGER.error("Size of vector {} is {} and differs from size of other vectors which is {}!", variable.getName(), variable.size(), size); //$NON-NLS-1$
}
}
this.indexColours = ColorFactory.makeRainbowColours(size);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body *
// ***************************************************************************
// ---------------------------------------------------------------------------
public List<BaseWidget> buildWidgetsFromVariables(Element template, Integer widgetId, BootstrapContext context, BootstrapCallback callback) throws BuildException {
List<BaseWidget> widgets = null;
Map<String, Variable<?>> systemVariables = new HashMap<>();
index = 0;
context.setProperty(Templating.HANDLE_ID_PROPERTY, widgetId);
context.setProperty(Templating.SIZE_OF_VECTORS_PROPERTY, size);
for (Variable<?> systemVariable : variables) {
systemVariables.put(systemVariable.getName(), systemVariable);
}
if (size > 0) {
widgets = TangibleObjectBootstrapper.buildWidgetFromTemplate(template, context, this);
for (BaseWidget widget : widgets) {
List<Variable<?>> connected;
if (widget.getClass().isAssignableFrom(VariableBased.class)) {
VariableBased display = (VariableBased) widget;
connected = display.connectWithSystemVariables(systemVariables);
if (widget.getClass().isAssignableFrom(InputChangeListener.class)) {
InputChangeListener listener = (InputChangeListener) widget;
for (Variable<?> connectedVariable : connected)
connectedVariable.addListener(listener);
}
}
}
} else {
LOGGER.warn("Encountered a Widget without any variables. Won't build Widget! ID of offending Widget is {}", widgetId); //$NON-NLS-1$
}
return widgets;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext preInstantiation(Element node, BootstrapContext context) {
for (VectorVariable<?> variable : variables) {
context.setProperty(variable.getName(), variable.get(index));
}
Color colour = indexColours.get(index);
context.setProperty(Templating.INDEX_COLOUR_PROPERTY, colour.getRGB());
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext postInstantiation(Element node, BootstrapContext context) {
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext next(BootstrapContext context) {
if (index < size) {
this.index++;
}
return context;
}
// ---------------------------------------------------------------------------
/** {@inheritDoc} */
@Override
public BootstrapContext reset(BootstrapContext context) {
this.index = 0;
return context;
}
// ---------------------------------------------------------------------------
}
......@@ -48,7 +48,7 @@ public class InputEvent extends EventObject {
* @param tick
* The turn index the event was triggered at.
*/
public InputEvent(Variable source, long tick) {
public InputEvent(Variable<?> source, long tick) {
super(source);
this.tick = tick;
}
......@@ -59,7 +59,7 @@ public class InputEvent extends EventObject {
* @param source
* The source of the event.
*/
public InputEvent(Variable source) {
public InputEvent(Variable<?> source) {
super(source);
this.tick = -1;
}
......@@ -72,4 +72,9 @@ public class InputEvent extends EventObject {
public long getTick() {
return tick;
}
@Override
public Variable<?> getSource() {
return (Variable<?>) this.source;
}
}
\ No newline at end of file
......@@ -41,9 +41,9 @@ public class Phenomenon {
/** The clock which may dictate the sampling rate and advancement of the phenomenon. */
private Clock clock;
/** The independent variables characterising the system. */
private ConcurrentHashMap<String, Variable> independentVariables;
private ConcurrentHashMap<String, Variable<?>> independentVariables;
/** The variables depending on the system and its inputs. */
private ConcurrentHashMap<String, Variable> dependentVariables;
private ConcurrentHashMap<String, Variable<?>> dependentVariables;
/** The system computing dependent variables from input independent variables. */
private lu.list.itis.dkd.tui.cps.system.System system;
/** Field indicating whether the observation is to be driven by a clock. */
......@@ -62,8 +62,8 @@ public class Phenomenon {
* Indication whether the observation of the phenomenon is to be driven by the ticking of
* a clock or is synchronous.
*/
public Phenomenon(ConcurrentHashMap<String, Variable> independentVariables,
ConcurrentHashMap<String, Variable> dependentVariables,
public Phenomenon(ConcurrentHashMap<String, Variable<?>> independentVariables,
ConcurrentHashMap<String, Variable<?>> dependentVariables,
lu.list.itis.dkd.tui.cps.system.System system, boolean clockDriven) {
clock = new Clock();
this.independentVariables = independentVariables;
......@@ -103,7 +103,7 @@ public class Phenomenon {
*
* @return The {@link Collection} of dependent variables.
*/
public Collection<Variable> getOutputs() {
public Collection<Variable<?>> getOutputs() {
return dependentVariables.values();
}
......@@ -115,7 +115,7 @@ public class Phenomenon {
* @return The instance of the {@link Variable} or <code>null</code> if no such {@link Variable}
* was defined.
*/
public @Nullable Variable getOutput(String variableName) {
public @Nullable Variable<?> getOutput(String variableName) {
return dependentVariables.get(variableName);
}
......@@ -124,7 +124,7 @@ public class Phenomenon {
*
* @return The value of independentVariables.
*/
public Collection<Variable> getInputs() {
public Collection<Variable<?>> getInputs() {
return independentVariables.values();
}
......
......@@ -22,6 +22,8 @@ package lu.list.itis.dkd.tui.cps.system;
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.system.executor.Executor;
import lu.list.itis.dkd.tui.cps.variable.Variable;
......@@ -30,6 +32,7 @@ import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.LinkedHashSet;
import javax.script.ScriptEngine;
......@@ -43,14 +46,15 @@ import javax.script.ScriptEngine;
*/
@NonNullByDefault
public class Equation {
private String name;
private Mapping mapping;
private Mapping lockedMapping;
@Nullable
// private ScriptEngine scriptEngine;
private Executor scriptExecutor;
private String script;
private boolean isolated;
private static Logger LOGGER = LoggerFactory.getLogger(Equation.class.getSimpleName());
private static final Logger LOGGER = LoggerFactory.getLogger(Equation.class.getSimpleName());
/**
* Constructor
......@@ -62,10 +66,12 @@ public class Equation {
* the variables in the script must coincide with the names of the variables in the
* mapping.
*/
public Equation(Mapping mapping, String script) {
public Equation(String name, Mapping mapping, String script) {
this.name = name;
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
this.isolated = false;
}
/**
......@@ -77,20 +83,26 @@ public class Equation {
return mapping;
}
/**
* Allows to isolate this equation. An isolated equation will not notify dependent equations
* when evaluation entailed changes in results.
*
* @param isolateIt
*/
public void setIsolated(boolean isolateIt) {
this.isolated = isolateIt;
}
public boolean isIsolated() {
return this.isolated;
}
/**
* Method called to evaluate the script of the equation with the variables provided by the
* mapping.
*/
public void evaluate() {
// Preconditions.checkState(scriptEngine != null);
// try {
// mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables()));
// } catch (ScriptException e) {
// Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "Exception while
// executing script!", e); //$NON-NLS-1$
// }
LinkedHashSet<Variable> dependentVariables;
public synchronized void evaluate() {
LinkedHashSet<Variable<?>> dependentVariables;
String evaluationErrors;
Preconditions.checkState(scriptExecutor != null);
......@@ -98,22 +110,43 @@ public class Equation {
try {
scriptExecutor.resetExecutionErrors();
for (Variable variable : lockedMapping.getIndependentVariables()) {
for (Variable<?> variable : lockedMapping.getIndependentVariables()) {
scriptExecutor.set(variable);
}
scriptExecutor.eval(this.script);
} catch (Exception exception) {
LOGGER.error("Error while evaluating script {}", this.script, exception); //$NON-NLS-1$
LOGGER.error("Error while evaluating script {}", this.script); //$NON-NLS-1$
LOGGER.error("Engine threw an exception {}", exception.toString()); //$NON-NLS-1$
}
dependentVariables = mapping.getDependentVariables();
for (Variable variable : dependentVariables) {
boolean consolidated = (dependentVariables.size() > 1);
HashMap<InputChangeListener, Variable<?>> consolidatedListeners = null;
if (consolidated)
consolidatedListeners = new HashMap<>();
for (Variable<?> variable : dependentVariables) {
variable.suspendListenerNotification(consolidated);
if (consolidated)
consolidatedListeners = variable.consolidateListeners(consolidatedListeners);
try {
variable = scriptExecutor.get(variable);
} catch (Exception exception) {
LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$
}
variable.suspendListenerNotification(false);
}
if (isolated && LOGGER.isInfoEnabled()) {
LOGGER.info("Equation {} evaluated in isolated mode! Dependent variables won't trigger dependent equations!", this.name); //$NON-NLS-1$
}
if (!isolated && consolidated && consolidatedListeners != null) {
for (InputChangeListener listener : consolidatedListeners.keySet()) {
Variable<?> variable = consolidatedListeners.get(listener);
listener.inputChanged(new InputEvent(variable));
}
}
evaluationErrors = scriptExecutor.getExecutionErrors();
......@@ -121,42 +154,13 @@ public class Equation {
if (evaluationErrors.length() > 0) {
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) {
LinkedHashSet<Variable<?>> independentVariables = mapping.getIndependentVariables();
for (Variable<?> variable : independentVariables) {
LOGGER.trace("{} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
}
/**
* Method used to replace variables with their actual values in the formula.
*
* @return The formula with variables replaced by their values, ready for evaluation.
*/
// private String replaceVariables() {
// String result = new String(script);
//
// for (Variable variable : lockedMapping.getIndependentVariables()) {
// result = result.replaceAll(variable.getName(), variable.getValue().toString());
// }
//
// for (Variable variable : lockedMapping.getDependentVariables()) {
// result = result.replaceAll(variable.getName(), variable.getValue().toString());
// }
//
// assert result != null;
// return result;
// }
/**
* Method for setting the script engine to use.
*
* @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/
// public void setScriptEngine(ScriptEngine engine) {
// scriptEngine = engine;
// }
/**
* Method for setting the script engine to use.
*
......@@ -176,7 +180,7 @@ public class Equation {
* @return <code>True</code> if the {@link Variable} instance is an independent variable that is
* part of this {@link Equation} isntance's computation.
*/
public boolean catersTo(Variable variable) {
public boolean catersTo(Variable<?> variable) {
return mapping.catersTo(variable);
}
......@@ -188,17 +192,8 @@ public class Equation {
lockedMapping = mapping.lock();
}
// /**
// * Method used to update the mapping with a variable, that is, to update the reference to a
// * variable so that the mapping will correctly map all changes of the variable. <br>
// * <br>
// * <u>Note:</u> This method depends on the equality of variables being by name and unit.
// *
// * @param variable
// * The variable to update the reference for.
// * @see Variable#equals(Object)
// */
// public void updateMapping(Variable variable) {
// mapping.updateVariableReference(variable);
// }
@Override
public String toString() {
return this.name;
}
}
\ No newline at end of file
......@@ -22,10 +22,12 @@ package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.cps.InputEvent;
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.concurrent.ConcurrentHashMap;
/**
......@@ -42,6 +44,8 @@ public class LinearEquationSystem extends System {
private ConcurrentHashMap<Mapping, Equation> equations;
// private ScriptEngine scriptEngine;
private static final Logger LOGGER = LoggerFactory.getLogger(LinearEquationSystem.class.getSimpleName());
/**
* Constructor issuing a super call and initialising the map of equations.
*
......@@ -54,9 +58,7 @@ public class LinearEquationSystem extends System {
public LinearEquationSystem(boolean lockToNesting) {
super();
equations = new ConcurrentHashMap<>();
// scriptEngine = new ScriptEngineManager().getEngineByName("js"); //$NON-NLS-1$
this.lockSystemForNesting = lockToNesting;
// assert scriptEngine != null : "Script engine cannot be null;"; //$NON-NLS-1$
}
/**
......@@ -76,6 +78,9 @@ public class LinearEquationSystem extends System {
@Override
public synchronized void clockTicked(long tick) {
super.clockTicked(tick);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Clock tick at {}...", tick); //$NON-NLS-1$
}
for (Equation equation : equations.values()) {
equation.evaluate();
......@@ -92,7 +97,10 @@ public class LinearEquationSystem extends System {
super.inputChanged(input);
for (Equation equation : equations.values()) {
if (equation.catersTo((Variable) input.getSource())) {
if (equation.catersTo(input.getSource())) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Equation {} triggered by variable {}...", equation.toString(), input.getSource().getName()); //$NON-NLS-1$
}
equation.evaluate();
}
}
......@@ -114,4 +122,10 @@ public class LinearEquationSystem extends System {
public ConcurrentHashMap<Mapping, Equation> getEquations() {
return equations;
}
@Override
public String toString() {
return this.equations.toString();
}
}
\ No newline at end of file
......@@ -36,8 +36,8 @@ import java.util.LinkedHashSet;
*/
@NonNullByDefault
public class Mapping {
private LinkedHashSet<Variable> independentVariables;
private LinkedHashSet<Variable> dependentVariables;
private LinkedHashSet<Variable<?>> independentVariables;
private LinkedHashSet<Variable<?>> dependentVariables;
/**
* Constructor initialising the mapping.
......@@ -47,7 +47,7 @@ public class Mapping {
* @param dependentVariable
* The dependent variable of the mapping.
*/
public Mapping(LinkedHashSet<Variable> independentVariables, LinkedHashSet<Variable> dependentVariables) {
public Mapping(LinkedHashSet<Variable<?>> independentVariables, LinkedHashSet<Variable<?>> dependentVariables) {
// Preconditions.checkArgument(!independentVariables.isEmpty(), "The set of input variables
// cannot be empty."); //$NON-NLS-1$
this.independentVariables = independentVariables;
......@@ -59,7 +59,7 @@ public class Mapping {
*
* @return The value of independentVariables.
*/
public LinkedHashSet<Variable> getIndependentVariables() {
public LinkedHashSet<Variable<?>> getIndependentVariables() {
return independentVariables;
}
......@@ -68,7 +68,7 @@ public class Mapping {
*
* @return The value of dependentVariables.
*/
public LinkedHashSet<Variable> getDependentVariables() {
public LinkedHashSet<Variable<?>> getDependentVariables() {
return dependentVariables;
}
......@@ -78,17 +78,25 @@ public class Mapping {
String separator = ""; //$NON-NLS-1$
StringBuilder renderer = new StringBuilder();
for (Variable variable : independentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
if (independentVariables != null) {
for (Variable<?> variable : independentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
} else {
renderer.append("n/a"); //$NON-NLS-1$
}
renderer.append(" => "); //$NON-NLS-1$
separator = ""; //$NON-NLS-1$
for (Variable variable : dependentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
if (dependentVariables != null) {
for (Variable<?> variable : dependentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
} else {
renderer.append("n/a"); //$NON-NLS-1$
}
return renderer.toString();
......@@ -133,8 +141,8 @@ public class Mapping {
* @return <code>True</code> if the {@link Variable} instance is an independent variable managed
* by this {@link Mapping} instance.
*/
public boolean catersTo(Variable variable) {
for (Variable _variable : independentVariables) {
public boolean catersTo(Variable<?> variable) {
for (Variable<?> _variable : independentVariables) {
if (_variable.equals(variable)) {
return true;
}
......@@ -149,13 +157,15 @@ public class Mapping {
* @return A deep copy of the {@link Mapping}.
*/
public Mapping lock() {
LinkedHashSet<Variable> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable variable : independentVariables) {
LinkedHashSet<Variable<?>> clonedIndependentVariables = new LinkedHashSet<>();
for (Variable<?> variable : independentVariables) {
clonedIndependentVariables.add(variable.clone());
}
LinkedHashSet<Variable> clonedDependentVariables = new LinkedHashSet<>();
for (Variable variable : dependentVariables) {
clonedDependentVariables.add(variable.clone());
LinkedHashSet<Variable<?>> clonedDependentVariables = new LinkedHashSet<>();
if (dependentVariables != null) {
for (Variable<?> variable : dependentVariables) {
clonedDependentVariables.add(variable.clone());
}
}
return new Mapping(clonedIndependentVariables, clonedDependentVariables);
......
......@@ -25,6 +25,11 @@ import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.InputDriver;
import lu.list.itis.dkd.tui.cps.InputEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/**
......@@ -37,14 +42,16 @@ import java.util.Vector;
@NonNullByDefault
public abstract class System implements InputDriver, InputChangeListener {
/** Field holding the {@link Vector} of nested {@link System} instances. */
protected Vector<System> nestedSystems;
protected List<System> nestedSystems;
protected boolean lockSystemForNesting = true;
private static final Logger logger = LoggerFactory.getLogger(System.class.getSimpleName());
/**
* Constructor.
*/
public System() {
nestedSystems = new Vector<>();
nestedSystems = new ArrayList<>();
}
/**
......@@ -54,7 +61,12 @@ public abstract class System implements InputDriver, InputChangeListener {
* The {@link System} instance to add.
*/
public void nestSystem(System system) {
nestedSystems.add(system);
if (!nestedSystems.contains(system)) {
nestedSystems.add(system);
} else {
logger.trace("System {} is already known as a nested system!", system); //$NON-NLS-1$
}
}
/**
......@@ -66,11 +78,14 @@ public abstract class System implements InputDriver, InputChangeListener {
*/
@Override
public synchronized void inputChanged(InputEvent input) {
saveState();
for (System nestedSystem : nestedSystems) {
if (nestedSystem != null)
nestedSystem.saveState();
if (lockSystemForNesting) {
saveState();
for (System nestedSystem : nestedSystems) {
if (nestedSystem != null)
nestedSystem.saveState();
}
}
for (System nestedSystem : nestedSystems) {
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2017. All rights reserved. If you wish
* to use this code for any purpose, please contact the author(s).
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import java.util.List;
import java.util.Map;
/**
* @author Nico Mack [nico.mack@list.lu]
* @since 2.5
* @version 2.5.0
*/
public interface VariableBased {
public List<Variable<?>> connectWithSystemVariables(Map<String, Variable<?>> systemVariables);
}
......@@ -32,14 +32,16 @@ abstract public class Executor {
executionErrors.reset();
}
abstract public void resetContext();
@SuppressWarnings("unused")
public void resolve(List<Import> imports) {
LOGGER.warn("Imports not supported by Executor!"); //$NON-NLS-1$
}
abstract public void set(Variable variable);
abstract public void set(Variable<?> variable);
abstract public boolean eval(String script);
abstract public Variable get(Variable variable);
abstract public Variable<?> get(Variable<?> variable);
}
......@@ -7,6 +7,8 @@ import org.slf4j.LoggerFactory;
import java.util.Properties;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
......@@ -28,10 +30,13 @@ public class JavascriptExecutor extends Executor {
}
@Override
public void set(Variable variable) {
public void set(Variable<?> variable) {
// TODO Rely on ExecutorScope annotations to generalize setting of multi-value variables
engine.put(variable.getName(), variable.getValue());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
......@@ -41,8 +46,8 @@ public class JavascriptExecutor extends Executor {
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$
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
}
} catch (ScriptException exception) {
this.executionErrors.append(exception.toString());
......@@ -54,11 +59,19 @@ 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$
public Variable<?> get(Variable<?> variable) {
variable.setValueFromObject(result);
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Result {} = {}", variable.getName(), result); //$NON-NLS-1$
}
return variable;
}
/** {@inheritDoc} */
@Override
public void resetContext() {
Bindings context = engine.getBindings(ScriptContext.ENGINE_SCOPE);
context.clear();
engine.setBindings(context, ScriptContext.ENGINE_SCOPE);
}
}
......@@ -44,11 +44,11 @@ public class OctaveExecutor extends Executor {
}
@Override
public void set(Variable variable) {
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$
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
......@@ -57,21 +57,27 @@ public class OctaveExecutor extends Executor {
long elapsed = System.currentTimeMillis();
engine.eval(script);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
}
return true;
}
@Override
public Variable get(Variable variable) {
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$
variable.setValueFromObject(result.get(1));
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Result {} = {}", variable.getName(), result.get(1)); //$NON-NLS-1$
}
return variable;
}
/** {@inheritDoc} */
@Override
public void resetContext() {
// TODO figure out a way to clear engine context
}
}
......@@ -28,16 +28,24 @@ import org.eclipse.osgi.util.NLS;
* @version 1.3.0
*/
@SuppressWarnings({"javadoc", "nls"})
public class Externalization extends NLS {
private static final String BUNDLE_NAME = "lu.list.itis.dkd.tui.cps.utility.externalization";
public class EquationSystemBundle extends NLS {
private static final String BUNDLE_NAME = "lu.list.itis.dkd.tui.cps.utility.equationsystem";
public static String EXECUTOR_NAMESPACE;
public static String NAMESPACE_SEPARATOR;
public static String EXECUTOR_POSTFIX;
public static String EXECUTOR_CLASS;
public static String NUMERIC_VARIABLE_CLASS;
public static String LOGIC_VARIABLE_CLASS;
public static String TEXT_VARIABLE_CLASS;
public static String SPATIAL_VARIABLE_CLASS;
public static String VECTOR_VARIABLE_CLASS;
public static String EQUATION_ELEMENT;
public static String MODE_ATTRIBUTE;
public static String EQUATIONS_ELEMENT;
public static String INVOKE_ELEMENT;
public static String EXECUTOR_ATTRIBUTE;
public static String NAME_ATTRIBUTE;
public static String OUTPUT_ELEMENT;
public static String OUTPUTS_ELEMENT;
......@@ -46,6 +54,7 @@ public class Externalization extends NLS {
public static String PARAMETERS_ELEMENT;
public static String PERIODIC_ATTRIBUTE;
public static String RESULT_ELEMENT;
public static String EPSILON_ATTRIBUTE;
public static String EQUATE_ATTRIBUTE;
public static String RESULTS_ELEMENT;
public static String IMPORT_ELEMENT;
......@@ -53,20 +62,29 @@ public class Externalization extends NLS {
public static String FROM_ATTRIBUTE;
public static String IMPORTS_ELEMENT;
public static String SYSTEM_ELEMENT;
public static String DISPLAY_NAME_ATTRIBUTE;
public static String TYPE_ATTRIBUTE;
public static String UNIT_ATTRIBUTE;
public static String MINIMUM_ATTRIBUTE;
public static String MAXIMUM_ATTRIBUTE;
public static String SCALE_ATTRIBUTE;
public static String DECIMALS_ATTRIBUTE;
public static String TYPE_NODE;
public static final String EMPTY_STRING = "";
public static final String LOGIC_TYPE = "logic";
public static final String NUMERIC_TYPE = "numeric";
public static final String SPATIAL_TYPE = "spatial";
public static final String TEXT_TYPE = "text";
public static final String VECTOR_TYPE = "vector";
public static final String ISOLATED_VALUE = "isolated";
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Externalization.class);
NLS.initializeMessages(BUNDLE_NAME, EquationSystemBundle.class);
}
private Externalization() {}
private EquationSystemBundle() {}
}