...
 
Commits (12)
......@@ -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,15 +80,28 @@
<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>LIST</id>
<name>Artifacts</name>
<url>https://artefacts.list.lu/libs-release-local</url>
</repository>
<repository>
<id>LIST</id>
<name>Artifacts</name>
<url>https://artefacts.list.lu/libs-release-local</url>
</repository>
<!-- <repository>
<id>Kenai</id>
<name>Kenai</name>
......@@ -97,4 +110,4 @@
</repositories>
</project>
\ No newline at end of file
</project>
/**
* 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.variable.Variable;
import lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable;
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 lu.list.itis.dkd.tui.widget.DisplayWidget;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
/**
* @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 Vector<Color> variableColours;
private Integer index;
// ***************************************************************************
// * Constants *
// ***************************************************************************
private static 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;
index = 0;
context.setProperty(Templating.HANDLE_ID_PROPERTY, widgetId);
context.setProperty(Templating.NUMBER_OF_VARIABLES_PROPERTY, variables.size());
variableIterator = variables.iterator();
if (variableIterator.hasNext()) {
this.variable = variableIterator.next();
widgets = TangibleObjectBootstrapper.buildWidgetFromTemplate(template, context, this);
for (BaseWidget widget : widgets) {
if (widget.getClass().isAssignableFrom(DisplayWidget.class)) {
DisplayWidget display = (DisplayWidget) widget;
display.setVariables(this.variables);
for (Variable<?> displayVariable : variables)
displayVariable.addListener(display);
}
}
} 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_UNIT_PROPERTY, variable.getUnit());
if (variable instanceof TangibleNumericalVariable) {
TangibleNumericalVariable tangibleVariable = (TangibleNumericalVariable) variable;
context.setProperty(Templating.VARIABLE_MINVALUE_PROPERTY, tangibleVariable.getMinValue());
context.setProperty(Templating.VARIABLE_MAXVALUE_PROPERTY, tangibleVariable.getMaxValue());
context.setProperty(Templating.VARIABLE_SCALE_PROPERTY, tangibleVariable.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.Externalization;
import lu.list.itis.dkd.tui.cps.variable.BooleanVariable;
import lu.list.itis.dkd.tui.cps.variable.SpatialVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.cps.variable.tangible.TangibleNumericalVariable;
import lu.list.itis.dkd.tui.exception.BuildException;
import lu.list.itis.dkd.tui.utility.Point;
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, Externalization.NAME_ATTRIBUTE, BootstrappingUtils.MANDATORY, null, context);
String type = BootstrappingUtils.getContentAsString(variableNode, Externalization.TYPE_NODE, BootstrappingUtils.MANDATORY, null, context);
switch (type) {
case Externalization.NUMERIC_TYPE:
String unit = BootstrappingUtils.getContentAsString(variableNode, Externalization.UNIT_ATTRIBUTE, BootstrappingUtils.OPTIONAL, Externalization.EMPTY_STRING, context);
double minValue = BootstrappingUtils.getContentAsDouble(variableNode, Externalization.MINIMUM_ATTRIBUTE, BootstrappingUtils.OPTIONAL, -Double.MAX_VALUE, context);
double maxValue = BootstrappingUtils.getContentAsDouble(variableNode, Externalization.MAXIMUM_ATTRIBUTE, BootstrappingUtils.OPTIONAL, Double.MAX_VALUE, context);
double scale = BootstrappingUtils.getContentAsDouble(variableNode, Externalization.SCALE_ATTRIBUTE, BootstrappingUtils.OPTIONAL, 1.0, context);
double numericValue = BootstrappingUtils.getContentAsDouble(variableNode, Externalization.INITIAL_ATTRIBUTE, BootstrappingUtils.OPTIONAL, 0.0, context);
TangibleNumericalVariable tangibleVariable = new TangibleNumericalVariable(name, unit, numericValue);
tangibleVariable.setMinValue(minValue);
tangibleVariable.setMaxValue(maxValue);
tangibleVariable.setScale(scale);
variable = tangibleVariable;
break;
case Externalization.LOGIC_TYPE:
boolean booleanValue = BootstrappingUtils.getContentAsBoolean(variableNode, Externalization.INITIAL_ATTRIBUTE, BootstrappingUtils.OPTIONAL, false, context);
BooleanVariable booleanVariable = new BooleanVariable(name, booleanValue);
variable = booleanVariable;
break;
case Externalization.SPATIAL_TYPE:
Element position = variableNode.getChild("position"); //$NON-NLS-1$
Point pos = new Point(position, context, callback);
String state = pos.getState().toString();
SpatialVariable spatialVariable = new SpatialVariable(name, state, pos);
variable = spatialVariable;
break;
default:
throw new BuildException("Don't know how to build a Variable of type " + type); //$NON-NLS-1$
}
return variable;
}
}
......@@ -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();
}
......@@ -136,4 +136,4 @@ public class Phenomenon {
public lu.list.itis.dkd.tui.cps.system.System getSystem() {
return system;
}
}
\ No newline at end of file
}
......@@ -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,12 +46,13 @@ 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());
......@@ -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,21 +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();
......@@ -120,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.
*
......@@ -175,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);
}
......@@ -187,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);
// }
}
\ No newline at end of file
@Override
public String toString() {
return this.name;
}
}
......@@ -92,7 +92,7 @@ public class LinearEquationSystem extends System {
super.inputChanged(input);
for (Equation equation : equations.values()) {
if (equation.catersTo((Variable) input.getSource())) {
if (equation.catersTo((Variable<?>) input.getSource())) {
equation.evaluate();
}
}
......
......@@ -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,7 +78,7 @@ public class Mapping {
String separator = ""; //$NON-NLS-1$
StringBuilder renderer = new StringBuilder();
for (Variable variable : independentVariables) {
for (Variable<?> variable : independentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
......@@ -86,7 +86,7 @@ public class Mapping {
renderer.append(" => "); //$NON-NLS-1$
separator = ""; //$NON-NLS-1$
for (Variable variable : dependentVariables) {
for (Variable<?> variable : dependentVariables) {
renderer.append(separator).append(variable.getName());
separator = ", "; //$NON-NLS-1$
}
......@@ -133,8 +133,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,12 +149,12 @@ 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) {
LinkedHashSet<Variable<?>> clonedDependentVariables = new LinkedHashSet<>();
for (Variable<?> variable : dependentVariables) {
clonedDependentVariables.add(variable.clone());
}
......@@ -180,4 +180,4 @@ public class Mapping {
// independentVariables.add(variable);
// }
// }
}
\ No newline at end of file
}
......@@ -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);
}
package lu.list.itis.dkd.tui.cps.system.executor;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import lu.list.itis.dkd.tui.cps.variable.SpatialVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import org.slf4j.Logger;
......@@ -7,6 +9,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 +32,35 @@ 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$
public void set(Variable<?> variable) {
switch (variable.getType()) {
case Externalization.NUMERIC_TYPE:
engine.put(variable.getName(), variable.getValue());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
break;
case Externalization.SPATIAL_TYPE:
engine.put(variable.getName() + "_x", ((SpatialVariable) variable).getValue().getX()); //$NON-NLS-1$
engine.put(variable.getName() + "_y", ((SpatialVariable) variable).getValue().getY()); //$NON-NLS-1$
engine.put(variable.getName() + "_z", ((SpatialVariable) variable).getValue().getAngle()); //$NON-NLS-1$
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {,,}", ((SpatialVariable) variable).getName(), ((SpatialVariable) variable).getValue().getX(), ((SpatialVariable) variable).getValue().getY(), ((SpatialVariable) variable).getValue().getAngle()); //$NON-NLS-1$
}
break;
default:
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Unable to set variable {}", variable.getName()); //$NON-NLS-1$
}
break;
}
}
......@@ -54,11 +83,21 @@ 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);
}
}
/**
* 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.executor;
import lu.list.itis.dkd.tui.cps.variable.TextVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import lu.list.itis.dkd.tui.network.adapter.MQTTPublisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Nathan Bonnemberger
*/
// TODO: Needs adjustments to remove script eval error
public class MqttExecutor extends Executor {
private Map<String, Object> parameters;
private String MQTTPort;
private String MQTTBroker;
private String MQTTPublisherId;
private MQTTPublisher mqtt;
private static final String MQTT_BROKER_ADDRESS = "mqtt.broker.address"; //$NON-NLS-1$
private static final String MQTT_BROKER_PORT = "mqtt.broker.port"; //$NON-NLS-1$
private static final String MQTT_BROKER_PUBLISHERID = "mqtt.broker.publisherid"; //$NON-NLS-1$
private static final Pattern MQTT_VAR_PATTERN = Pattern.compile("\\{([a-z0-9\\-_]+)\\}", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
private static Logger LOGGER = LoggerFactory.getLogger(MqttExecutor.class.getSimpleName());
/**
* Default constructor
*
* @param properties
*
*/
public MqttExecutor(Properties properties) {
super(properties);
this.parameters = new HashMap<>();
MQTTBroker = properties.getProperty(MQTT_BROKER_ADDRESS);
MQTTPort = properties.getProperty(MQTT_BROKER_PORT);
MQTTPublisherId = properties.getProperty(MQTT_BROKER_PUBLISHERID);
mqtt = new MQTTPublisher(properties);
}
private void interpolate(String message, List<String> placeholders, Map<String, Object> parameters, boolean positionalParameters) {
Matcher interpolator;
String payload;
String topic;
int position = 0;
StringBuffer interpolated;
int index = 1;
int group = 1;
placeholders.clear();
interpolator = MQTT_VAR_PATTERN.matcher(message);
interpolated = new StringBuffer();
while (interpolator.find()) {
interpolated.append(message.substring(position, interpolator.start()));
position = interpolator.start();
if (group == 1) {
payload = interpolator.group(1);
if ((payload != null) && (payload.length() > 0)) {
placeholders.add(payload);
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(index++);
} else {
interpolated.append(interpolated.substring(interpolator.start(), interpolator.end()));
}
}
if (group == 2) {
topic = interpolator.group(1);
if ((topic != null) && (topic.length() > 0)) {
placeholders.add(topic);
interpolated.append("?"); //$NON-NLS-1$
if (positionalParameters)
interpolated.append(index++);
} else {
interpolated.append(interpolated.substring(interpolator.start(), interpolator.end()));
}
}
position = interpolator.end();
}
interpolated.append(interpolated.substring(interpolator.start(), interpolator.end()));
}
/** {@inheritDoc} */
@Override
public void set(Variable<?> variable) {
parameters.put(variable.getName(), variable.getValue());
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Parameter -> {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
/** {@inheritDoc} */
@Override
public boolean eval(String script) {
long elapsed = System.currentTimeMillis();
List<String> variables = new ArrayList<String>();
this.interpolate(script, variables, this.parameters, false);
String payload;
String topic;
boolean success = false;
try {
// TODO: somehow populate payload and topic Strings with values of TextVariables whose
// name are contained in variables
TextVariable payVar = retrieveVariableByName(variables.get(0));
TextVariable topVar = retrieveVariableByName(variables.get(1));
payload = payVar.getValue();
topic = topVar.getValue();
mqtt.MQTTpublish(topic, payload);
success = true;
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Eval took {} ms | {}", elapsed, script); //$NON-NLS-1$
}
} catch (Exception e) {
LOGGER.error("Failed to send message!", e); //$NON-NLS-1$
}
return success;
}
/**
* Simple method to retrieve a variable based on its name in the parameters
*
* @param name
*/
private TextVariable retrieveVariableByName(String name) {
return (TextVariable) parameters.get(name);
}
/**
* {@inheritDoc}
*
* @param <B>
*/
@Override
public Variable<?> get(Variable<?> variable) {
// TODO Auto-generated method stub
return null;
}
/** {@inheritDoc} */
@Override
public void resetContext() {
// TODO Auto-generated method stub
}
}
\ No newline at end of file
package lu.list.itis.dkd.tui.cps.system.executor;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import lu.list.itis.dkd.tui.cps.variable.SpatialVariable;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import org.slf4j.Logger;
......@@ -44,11 +46,40 @@ public class OctaveExecutor extends Executor {
}
@Override
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$
public void set(Variable<?> variable) {
switch (variable.getType()) {
case Externalization.NUMERIC_TYPE:
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$
}
break;
case Externalization.SPATIAL_TYPE:
// TODO: check if norm 'variable_x' is supported by Octave
Double numericValueX = Double.valueOf(((SpatialVariable) variable).getValue().getX());
Double numericValueY = Double.valueOf(((SpatialVariable) variable).getValue().getY());
Double numericValueZ = Double.valueOf(((SpatialVariable) variable).getValue().getAngle());
engine.put(variable.getName() + "_x", Octave.scalar(numericValueX)); //$NON-NLS-1$
engine.put(variable.getName() + "_y", Octave.scalar(numericValueY)); //$NON-NLS-1$
engine.put(variable.getName() + "_z", Octave.scalar(numericValueZ)); //$NON-NLS-1$
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {,,}", ((SpatialVariable) variable).getName(), ((SpatialVariable) variable).getValue().getX(), ((SpatialVariable) variable).getValue().getY(), ((SpatialVariable) variable).getValue().getAngle()); //$NON-NLS-1$
}
break;
default:
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Unable to set variable {}", variable.getName()); //$NON-NLS-1$
}
break;
}
}
......@@ -64,14 +95,22 @@ public class OctaveExecutor extends Executor {
}
@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
}
}
/**
* 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.utility;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public @interface ExecutorScope {
String identifier() default "";
}
......@@ -31,13 +31,21 @@ import org.eclipse.osgi.util.NLS;
public class Externalization extends NLS {
private static final String BUNDLE_NAME = "lu.list.itis.dkd.tui.cps.utility.externalization";
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;
......@@ -53,15 +61,24 @@ 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
......
EXECUTOR_CLASS=executor.class
NUMERIC_VARIABLE_CLASS=numeric.variable.class
LOGIC_VARIABLE_CLASS=logic.variable.class
TEXT_VARIABLE_CLASS=text.variable.class
SPATIAL_VARIABLE_CLASS=spatial.variable.class
VECTOR_VARIABLE_CLASS=vector.variable.class
EXECUTOR_NAMESPACE=lu.list.itis.dkd.tui.cps.system.executor
NAMESPACE_SEPARATOR=.
EXECUTOR_POSTFIX=Executor
EQUATIONS_ELEMENT=equations
EQUATION_ELEMENT=equation
MODE_ATTRIBUTE=mode
INVOKE_ELEMENT=invoke
EXECUTOR_ATTRIBUTE=executor
NAME_ATTRIBUTE=name
OUTPUTS_ELEMENT=outputs
OUTPUT_ELEMENT=output
PARAMETER_ELEMENT=parameter
DISPLAY_NAME_ATTRIBUTE=displayName
TYPE_ATTRIBUTE=type
INITIAL_ATTRIBUTE=initial
MINIMUM_ATTRIBUTE=minimum
......@@ -25,4 +35,5 @@ IMPORT_ELEMENT=import
FUNCTION_ATTRIBUTE=function
FROM_ATTRIBUTE=from
SYSTEM_ELEMENT=system
UNIT_ATTRIBUTE=unit
\ No newline at end of file
UNIT_ATTRIBUTE=unit
TYPE_NODE=type
......@@ -20,10 +20,11 @@
*/
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Vector;
/**
......@@ -31,14 +32,14 @@ import java.util.Vector;
* @since 1.1
* @version 1.3.1
*/
public class BooleanVariable extends Variable {
protected boolean value;
public class BooleanVariable extends Variable<Boolean> {
/**
* @param name
* @param value
*/
private static final Logger LOGGER = LoggerFactory.getLogger(BooleanVariable.class.getSimpleName());
public BooleanVariable(String name, boolean value) {
super(Externalization.LOGIC_TYPE, name, "boolean"); //$NON-NLS-1$
......@@ -47,27 +48,13 @@ public class BooleanVariable extends Variable {
/** {@inheritDoc} */
@Override
public Boolean getValue() {
return value;
}
/** {@inheritDoc} */
@Override
public void setValue(Object value) {
if (value instanceof Boolean) {
this.value = (Boolean) value;
} else {
this.value = (Boolean) valueFromString(value.toString());
}
for (InputChangeListener listener : listeners) {
listener.inputChanged(new InputEvent(this));
}
public void setValueFromObject(Object object) {
this.setValue(this.valueFromObject(object));
}
/** {@inheritDoc} */
@Override
public Variable clone() {
public Variable<Boolean> clone() {
BooleanVariable variable = new BooleanVariable(name, value);
variable.listeners = new Vector<>(listeners);
return variable;
......@@ -75,7 +62,25 @@ public class BooleanVariable extends Variable {
/** {@inheritDoc} */
@Override
public Object valueFromString(String stringValue) {
public Boolean valueFromString(String stringValue) {
return Boolean.parseBoolean(stringValue);
}
}
\ No newline at end of file
@Override
public Boolean valueFromObject(Object objectValue) {
Boolean converted = null;
if (objectValue == null) {
LOGGER.warn("Null value specified!"); //$NON-NLS-1$
return null;
}
if (objectValue instanceof Boolean) {
converted = (Boolean) objectValue;
} else {
converted = this.valueFromString(objectValue.toString());
}
return converted;
}
}
......@@ -22,11 +22,8 @@ package lu.list.itis.dkd.tui.cps.variable;
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;
......@@ -42,8 +39,7 @@ import java.util.Vector;
* @param <T>
*/
@NonNullByDefault
public class NumericalVariable extends Variable {
protected double value;
public class NumericalVariable extends Variable<Double> {
protected double minValue;
protected double maxValue;
protected double scale;
......@@ -69,9 +65,9 @@ public class NumericalVariable extends Variable {
format = new DecimalFormat();
format.setDecimalSeparatorAlwaysShown(false);
format.setMaximumFractionDigits(0);
format.setGroupingUsed(false);
// minValue = Double.MIN_VALUE;
minValue = -Double.MAX_VALUE;
maxValue = Double.MAX_VALUE;
scale = 1;
......@@ -85,15 +81,17 @@ public class NumericalVariable extends Variable {
* The root element of the variable containing, as text on child elements, all the
* necessary information to initialize the variable.
*/
public NumericalVariable(Element rootElement) {
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();
format.setDecimalSeparatorAlwaysShown(false);
format.setGroupingUsed(false);
}
// public NumericalVariable(Element rootElement) {
// super(Externalization.NUMERIC_TYPE, rootElement.getChildText("name"),
// rootElement.getChildText("unit")); //$NON-NLS-1$ //$NON-NLS-2$
// String valueContent = Strings.nullToEmpty(rootElement.getChildText("value")); //$NON-NLS-1$
// this.value = (valueContent.length() > 0) ? Double.parseDouble(valueContent) : 0.0;
//
// format = new DecimalFormat();
// format.setDecimalSeparatorAlwaysShown(false);
// format.setGroupingUsed(false);
//
// }
/**
* {@inheritDoc}<br>
......@@ -103,13 +101,10 @@ public class NumericalVariable extends Variable {
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder(format.format(value));
StringBuilder builder = new StringBuilder(format.format(value / scale));
if ((unit != null) && (unit.length() > 0)) {
// builder.append(" [").append(unit).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
builder.append(" ").append(unit); //$NON-NLS-1$ //$NON-NLS-2$
builder.append(" ").append(unit); //$NON-NLS-1$
}
return builder.toString();
}
......@@ -150,24 +145,28 @@ public class NumericalVariable extends Variable {
/** {@inheritDoc} */
@Override
public void setValue(Object value) {
Double newValue;
newValue = (Double) this.valueFromString(value.toString());
// newValue = (Double) value;
public void setValue(Double newValue) {
// Double newValue;
// newValue = (Double) this.valueFromString(value.toString());
if (newValue < this.minValue)
this.value = this.minValue;
newValue = this.minValue;
else if (newValue > this.maxValue)
this.value = this.maxValue;
else
this.value = newValue;
InputEvent event = new InputEvent(this);
for (InputChangeListener listener : listeners) {
// listener.inputChanged(new InputEvent(this));
listener.inputChanged(event);
}
newValue = this.maxValue;
super.setValue(newValue);
}
/** {@inheritDoc} */
@Override
public void setValueFromObject(Object object) {
this.setValue(this.valueFromObject(object));
}
/** {@inheritDoc} */
@Override
public Double getValue() {
return this.value;
}
/**
*
......@@ -224,12 +223,6 @@ public class NumericalVariable extends Variable {
return this.scale;
}
/** {@inheritDoc} */
@Override
public Double getValue() {
return value;
}
/**
*
* @param decimals
......@@ -254,7 +247,7 @@ public class NumericalVariable extends Variable {
/** {@inheritDoc} */
@Override
public Object valueFromString(String stringValue) {
public Double valueFromString(String stringValue) {
Double newValue = Double.valueOf(0);
try {
newValue = Double.parseDouble(stringValue);
......@@ -264,4 +257,19 @@ public class NumericalVariable extends Variable {
}
return newValue;
}
}
\ No newline at end of file
@Override
public Double valueFromObject(Object objectValue) {
Double converted = null;
if (objectValue == null)
return null;
if (objectValue instanceof Double) {
converted = (Double) objectValue;
} else
converted = this.valueFromString(objectValue.toString());
return converted;
}
}
/**
* 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.variable;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.utility.ExecutorScope;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import lu.list.itis.dkd.tui.utility.CoordinateState;
import lu.list.itis.dkd.tui.utility.Point;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author mack
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public class SpatialVariable extends Variable<Point> {
private static final Logger LOGGER = LoggerFactory.getLogger(SpatialVariable.class.getSimpleName());
private static final Pattern SPATIAL_STRING_PATTERN = Pattern.compile("([0-9]+\\.?[0-9]*)\\s*,\\s*([0-9]+\\.?[0-9]*)(\\s*,\\s*([0-9]+\\.?[0-9]*))?,(TableCoordinates|ScreenCoordinates|CameraCoordinates)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
/**
* @param type
* @param name
* @param unit
*/
public SpatialVariable(String name, String unit, Point value) {
super(Externalization.SPATIAL_TYPE, name, unit);
this.value = value;
}
/**
* {@inheritDoc}<br>
* <br>
*
* The hash code is based on the <code>toString()</code> representation of this class.
*/
@Override
public int hashCode() {
if (this.value == null)
return 0;
return this.value.hashCode();
}
/**
* {@inheritDoc}<br>
* <br>
*
* The equality test is base on equality of name, unit, and value.
*/
@Override
public boolean equals(@Nullable Object object) {
if (object == null)
return false;
if (object == this)
return true;
if (object instanceof SpatialVariable) {
SpatialVariable variable = (SpatialVariable) object;
if (name.equals(variable.getName()) && unit.equals(variable.getUnit()) && variable.getValue().equals(value)) {
return true;
}
}
return false;
}
/** {@inheritDoc} */
@Override
public void setValueFromObject(Object object) {
this.setValue(this.valueFromObject(object));
}
/** {@inheritDoc} */
@Override
public Variable<Point> clone() {
SpatialVariable variable = new SpatialVariable(name, unit, value);
variable.listeners = new Vector<>(listeners);
return variable;
}
/** {@inheritDoc} */
@Override
public Point valueFromString(String stringValue) {
Point newPoint = null;
// CoordinateState state = null;
Matcher pointMatcher = SPATIAL_STRING_PATTERN.matcher(stringValue);
if (pointMatcher.matches()) {
try {
float a = 0;
float x = (float) Double.parseDouble(pointMatcher.group(1));
float y = (float) Double.parseDouble(pointMatcher.group(2));
if (pointMatcher.group(4) != null) {
a = (float) Double.parseDouble(pointMatcher.group(4));
}