@move "http://www.simantics.org/Sysdyn-1.1/" "HasHead" "Variable/HasHead"\r
_\r
@move "http://www.simantics.org/Sysdyn-1.1/" "SharedModuleOntolofgy" "SharedModuleOntology"\r
+ _\r
+ @move "http://www.simantics.org/Sysdyn-1.1/" "HasUnit" "Variable/unit"\r
\r
\r
FROM16TO17.OrderedSetsToLists : L0.OrderedSetToListMigrationStep\r
FUNCTIONS.runChildren : L0.ExternalValue
-
-SYSDYN.HasUnit <R L0.HasProperty
- L0.HasRange L0.String
-
SYSDYN.HasRangeStart <R L0.HasProperty
L0.HasRange L0.Double
VALIDATIONS.Enumerations : L0.Library\r
VALIDATIONS.Enumerations.enumerationIndexValidator : L0.Function\r
\r
+// ENUMERATIONS\r
+VALIDATIONS.Units : L0.Library\r
+VALIDATIONS.Units.unitValidator : L0.Function\r
+\r
SYSDYN.Variable\r
@VALIDATIONS.constraint\r
VALIDATIONS.ExpressionConstraint\r
VALIDATIONS.Dependencies.missingDependencyValidator \r
VALIDATIONS.Functions.baseRealizationFunction \r
\r
+SYSDYN.IndependentVariable\r
+ @VALIDATIONS.listeningConstraint\r
+ VALIDATIONS.UnitConstraint\r
+ VALIDATIONS.Units.UnitIssueSource\r
+ @L0.assert L0.HasName "UnitIssueSource"\r
+ VALIDATIONS.Units.unitValidator \r
+ VALIDATIONS.Functions.baseRealizationFunction\r
+ \r
VALIDATIONS.ExpressionIssue\r
@VALIDATIONS.issue\r
ISSUE.Severity.Error\r
L0.HasValueType "String"\r
VALIDATIONS.Functions.path \r
\r
- \r
+VALIDATIONS.UnitWarning\r
+ @VALIDATIONS.issue\r
+ ISSUE.Severity.Warning\r
+ VALIDATIONS.Units.unitWarningDescription : L0.Function\r
+ L0.HasValueType "String"\r
+ VALIDATIONS.Functions.path \r
+\r
\r
// IssueSource template\r
VALIDATIONS.constraint : L0.Template\r
public final Resource HasRangeStep;\r
public final Resource HasRangeStep_Inverse;\r
public final Resource HasTailTerminal;\r
- public final Resource HasUnit;\r
- public final Resource HasUnit_Inverse;\r
public final Resource HistoryDataset;\r
public final Resource HistoryDataset_FoundVariableNameNode;\r
public final Resource HistoryDataset_HistoryDatasetVariablesBrowseContext;\r
public final Resource Validations_NoSuchVariableIssue;\r
public final Resource Validations_RangeIssue;\r
public final Resource Validations_RangeWarning;\r
+ public final Resource Validations_UnitConstraint;\r
+ public final Resource Validations_UnitWarning;\r
+ public final Resource Validations_Units;\r
+ public final Resource Validations_Units_UnitIssueSource;\r
+ public final Resource Validations_Units_unitValidator;\r
+ public final Resource Validations_Units_unitWarningDescription;\r
public final Resource Validations_UnusedDependencyIssue;\r
public final Resource Validations_constraint;\r
public final Resource Validations_issue;\r
public static final String HasRangeStep = "http://www.simantics.org/Sysdyn-1.1/HasRangeStep";\r
public static final String HasRangeStep_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasRangeStep/Inverse";\r
public static final String HasTailTerminal = "http://www.simantics.org/Sysdyn-1.1/HasTailTerminal";\r
- public static final String HasUnit = "http://www.simantics.org/Sysdyn-1.1/HasUnit";\r
- public static final String HasUnit_Inverse = "http://www.simantics.org/Sysdyn-1.1/HasUnit/Inverse";\r
public static final String HistoryDataset = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset";\r
public static final String HistoryDataset_FoundVariableNameNode = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/FoundVariableNameNode";\r
public static final String HistoryDataset_HistoryDatasetVariablesBrowseContext = "http://www.simantics.org/Sysdyn-1.1/HistoryDataset/HistoryDatasetVariablesBrowseContext";\r
public static final String Validations_NoSuchVariableIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/NoSuchVariableIssue";\r
public static final String Validations_RangeIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeIssue";\r
public static final String Validations_RangeWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/RangeWarning";\r
+ public static final String Validations_UnitConstraint = "http://www.simantics.org/Sysdyn-1.1/Validations/UnitConstraint";\r
+ public static final String Validations_UnitWarning = "http://www.simantics.org/Sysdyn-1.1/Validations/UnitWarning";\r
+ public static final String Validations_Units = "http://www.simantics.org/Sysdyn-1.1/Validations/Units";\r
+ public static final String Validations_Units_UnitIssueSource = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/UnitIssueSource";\r
+ public static final String Validations_Units_unitValidator = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/unitValidator";\r
+ public static final String Validations_Units_unitWarningDescription = "http://www.simantics.org/Sysdyn-1.1/Validations/Units/unitWarningDescription";\r
public static final String Validations_UnusedDependencyIssue = "http://www.simantics.org/Sysdyn-1.1/Validations/UnusedDependencyIssue";\r
public static final String Validations_constraint = "http://www.simantics.org/Sysdyn-1.1/Validations/constraint";\r
public static final String Validations_issue = "http://www.simantics.org/Sysdyn-1.1/Validations/issue";\r
HasRangeStep = getResourceOrNull(graph, URIs.HasRangeStep);\r
HasRangeStep_Inverse = getResourceOrNull(graph, URIs.HasRangeStep_Inverse);\r
HasTailTerminal = getResourceOrNull(graph, URIs.HasTailTerminal);\r
- HasUnit = getResourceOrNull(graph, URIs.HasUnit);\r
- HasUnit_Inverse = getResourceOrNull(graph, URIs.HasUnit_Inverse);\r
HistoryDataset = getResourceOrNull(graph, URIs.HistoryDataset);\r
HistoryDataset_FoundVariableNameNode = getResourceOrNull(graph, URIs.HistoryDataset_FoundVariableNameNode);\r
HistoryDataset_HistoryDatasetVariablesBrowseContext = getResourceOrNull(graph, URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext);\r
Validations_NoSuchVariableIssue = getResourceOrNull(graph, URIs.Validations_NoSuchVariableIssue);\r
Validations_RangeIssue = getResourceOrNull(graph, URIs.Validations_RangeIssue);\r
Validations_RangeWarning = getResourceOrNull(graph, URIs.Validations_RangeWarning);\r
+ Validations_UnitConstraint = getResourceOrNull(graph, URIs.Validations_UnitConstraint);\r
+ Validations_UnitWarning = getResourceOrNull(graph, URIs.Validations_UnitWarning);\r
+ Validations_Units = getResourceOrNull(graph, URIs.Validations_Units);\r
+ Validations_Units_UnitIssueSource = getResourceOrNull(graph, URIs.Validations_Units_UnitIssueSource);\r
+ Validations_Units_unitValidator = getResourceOrNull(graph, URIs.Validations_Units_unitValidator);\r
+ Validations_Units_unitWarningDescription = getResourceOrNull(graph, URIs.Validations_Units_unitWarningDescription);\r
Validations_UnusedDependencyIssue = getResourceOrNull(graph, URIs.Validations_UnusedDependencyIssue);\r
Validations_constraint = getResourceOrNull(graph, URIs.Validations_constraint);\r
Validations_issue = getResourceOrNull(graph, URIs.Validations_issue);\r
<externalClass className="org.simantics.db.WriteGraph"/>\r
<class className="org.simantics.sysdyn.ui.validation.EnumerationFunction"/>\r
</namespace> \r
+ <namespace path="Units">\r
+ <externalClass className="org.simantics.db.Resource"/>\r
+ <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+ <externalClass className="org.simantics.db.ReadGraph"/>\r
+ <externalClass className="org.simantics.db.WriteGraph"/>\r
+ <class className="org.simantics.sysdyn.ui.validation.UnitFunction"/>\r
+ </namespace> \r
</namespace>\r
</extension>\r
<extension\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Label;\r
import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
import org.simantics.db.ReadGraph;\r
import org.simantics.db.Resource;\r
import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.management.ISessionContext;\r
+import org.simantics.issues.ontology.IssueResource;\r
import org.simantics.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.ui.properties.widgets.factories.ComboStringPropertyModifier;\r
import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
"or\n" +\r
"Auxiliary1|Auxiliary2|Auxiliary3");\r
\r
+ \r
+ Button validateUnits = new Button(composite, support, SWT.CHECK);\r
+ validateUnits.setText("Validate units");\r
+ validateUnits.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+ @Override\r
+ public Boolean perform(ReadGraph graph, Resource model) throws DatabaseException {\r
+ Resource unitIssueSource = graph.syncRequest(\r
+ new PossibleObjectWithType(model, \r
+ Layer0X.getInstance(graph).Activates, \r
+ SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource));\r
+ Boolean result = graph.getPossibleRelatedValue(unitIssueSource, IssueResource.getInstance(graph).IssueSource_active, Bindings.BOOLEAN);\r
+ return Boolean.TRUE.equals(result);\r
+ }\r
+ });\r
+ \r
+ validateUnits.addSelectionListener(new SelectionListenerImpl<Resource>(context){\r
+\r
+ @Override\r
+ public void apply(WriteGraph graph, Resource model) throws DatabaseException {\r
+ Resource unitIssueSource = graph.syncRequest(\r
+ new PossibleObjectWithType(model, \r
+ Layer0X.getInstance(graph).Activates, \r
+ SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource));\r
+ IssueResource ISSUE = IssueResource.getInstance(graph);\r
+ Boolean result = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN);\r
+ if(result == null)\r
+ result = false;\r
+ graph.claimLiteral(unitIssueSource, ISSUE.IssueSource_active, Boolean.FALSE.equals(result));\r
+ }\r
+ \r
+ });\r
+ \r
+ \r
// Scrolled composite settings\r
sc.setContent(composite);\r
sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
import org.simantics.db.service.VirtualGraphSupport;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo;\r
import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes;\r
import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
if (model != null) {\r
Collection<Resource> variables = graph.getObjects(model, l0.ConsistsOf);\r
for(Resource v : variables) {\r
- Object unit = graph.getPossibleRelatedValue(v, sr.HasUnit);\r
+ Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit);\r
if (unit != null && !map.keySet().contains(unit)) {\r
map.put((String)unit, (String)unit);\r
\r
\r
@Override\r
public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
- String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HasUnit);\r
+ String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).Variable_unit);\r
if(unit == null)\r
return "";\r
else \r
\r
@Override\r
public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
- graph.claimLiteral(input, SysdynResource.getInstance(graph).HasUnit, text);\r
+ graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit);\r
+ graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text);\r
+ \r
+ Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf);\r
+ SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+ SysdynModel sm = smm.getModel(graph, conf);\r
+ sm.getMapping().domainModified(input);\r
+ sm.update(graph);\r
}\r
});\r
\r
public static String getParameterExpression(IndependentVariable variable) throws DatabaseException {\r
String result = null;\r
try {\r
- result = variable.getExpressions().get(0).getExpression(variable);\r
+ result = variable.getExpressions().get(0).getExpression();\r
if(result.contains("/* Actual value read from init file */"))\r
result = result.substring(0, result.indexOf("/* Actual value read from init file */"));\r
} catch (NullPointerException e) {\r
// Get model configuration\r
SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
SysdynModel model = sdm.getModel(configuration);\r
- try {\r
- model.update();\r
- } catch (DatabaseException e1) {\r
- e1.printStackTrace();\r
- }\r
+// try {\r
+// model.update();\r
+// } catch (DatabaseException e1) {\r
+// e1.printStackTrace();\r
+// }\r
Configuration conf = model.getConfiguration();\r
\r
// Check variable references\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.adapter.Template;\r
import org.simantics.document.DocumentResource;\r
+import org.simantics.issues.ontology.IssueResource;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.layer0.utils.direct.GraphUtils;\r
import org.simantics.modeling.ModelingResources;\r
sr.Validations_Enumerations_EnumerationIssueSource,\r
L0X.IsActivatedBy, model,\r
l0.PartOf, model\r
- ); \r
+ ); \r
+ \r
+ GraphUtils.create2(g,\r
+ sr.Validations_Units_UnitIssueSource,\r
+ L0X.IsActivatedBy, model,\r
+ l0.PartOf, model,\r
+ IssueResource.getInstance(g).IssueSource_active, false\r
+ ); \r
\r
Resource conf = GraphUtils.create2(g,\r
sr.Configuration,\r
final Resource project = SimanticsUI.getProject().get();\r
if(project == null) return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model: project not found", null);\r
\r
- beginTask(monitor, "Import model", 8);\r
+ beginTask(monitor, "Import model", 9);\r
\r
Activator.getDefault().getPreferenceStore().setValue(IMPORTMODELTPATH, (new File(path)).getParent());\r
\r
subTask(monitor, "Add enumeration issue source");\r
addEnumerationIssueSource(graph, ModelRoot);\r
worked(monitor, 1);\r
+ subTask(monitor, "Add unit issue source");\r
+ addUnitIssueSource(graph, ModelRoot);\r
+ worked(monitor, 1);\r
subTask(monitor, "Add shadow profile");\r
addShadowProfile(graph, ModelRoot);\r
worked(monitor, 1); \r
\r
}\r
\r
+\r
});\r
\r
if(status != null)\r
} \r
}\r
\r
+\r
+ private static void addUnitIssueSource(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Layer0X L0X = Layer0X.getInstance(graph); \r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Collection<Resource> unitIssueSources = graph.syncRequest(new ObjectsWithType(modelRoot, L0.ConsistsOf, sr.Validations_Units_UnitIssueSource));\r
+ if(unitIssueSources.isEmpty()) {\r
+ GraphUtils.create2(graph,\r
+ sr.Validations_Units_UnitIssueSource,\r
+ L0X.IsActivatedBy, modelRoot,\r
+ L0.PartOf, modelRoot,\r
+ IssueResource.getInstance(graph).IssueSource_active, false\r
+ ); \r
+ } \r
+ }\r
+ \r
private static void addShadowProfile(WriteGraph graph, Resource modelRoot) throws DatabaseException {\r
DiagramResource DIA = DiagramResource.getInstance(graph);\r
SysdynResource SR = SysdynResource.getInstance(graph);\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Issue;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.issues.common.IssueUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.expressions.IExpression;\r
+\r
+public class UnitFunction {\r
+ \r
+ @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+ public static List<Issue> unitValidator(ReadGraph graph, Resource independentVariable) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+ \r
+ if(independentVariable == null)\r
+ return Collections.emptyList();\r
+ \r
+ Resource configuration = graph.getPossibleObject(independentVariable, L0.PartOf);\r
+ if(configuration == null)\r
+ return Collections.emptyList();\r
+ \r
+ // Make sure unit updates are listened to\r
+ Resource unitResource = graph.getPossibleObject(independentVariable, SR.Variable_unit);\r
+ String unit = graph.getPossibleRelatedValue(independentVariable, SR.Variable_unit);\r
+ if(unit == null || unit.trim().length() == 0)\r
+ return Collections.<Issue>singletonList(new StandardIssue(SR.Validations_UnitWarning, independentVariable));\r
+ \r
+ Resource expressionList = graph.getPossibleObject(independentVariable, SR.Variable_expressionList);\r
+ \r
+ if(expressionList == null)\r
+ return Collections.emptyList();\r
+\r
+ \r
+ SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+ SysdynModel sm = smm.getModel(graph, configuration);\r
+ sm.getMapping().domainModified(independentVariable);\r
+\r
+ sm.update(graph);\r
+ Object var = sm.getMapping().get(independentVariable);\r
+\r
+ ArrayList<Issue> issues = new ArrayList<Issue>();\r
+\r
+ for(Resource expression : ListUtils.toList(graph, expressionList)) {\r
+ for(Resource r : graph.getObjects(expression, SR.Expression_equation)) {\r
+ graph.getValue(r);\r
+ }\r
+ \r
+ sm.getMapping().domainModified(expression);\r
+ sm.update(graph);\r
+ \r
+ Object expr = sm.getMapping().get(expression);\r
+\r
+ if(expr != null && var != null && expr instanceof IExpression && var instanceof IndependentVariable) {\r
+ String result = ((IExpression)expr).matchUnits(graph, sm.getMapping());\r
+ if(result != null) {\r
+ Issue issue = new StandardIssue(SR.Validations_UnitWarning, independentVariable, expression, unitResource);\r
+ issues.add(issue);\r
+ }\r
+ }\r
+ }\r
+\r
+ return issues;\r
+ }\r
+\r
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+ public static String unitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+ List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+ \r
+ if(contexts.size() == 0)\r
+ return "Error, No contexts";\r
+ \r
+ Resource variable = contexts.get(0);\r
+ String unit = graph.getPossibleRelatedValue(variable, SysdynResource.getInstance(graph).Variable_unit);\r
+\r
+ if(unit == null || unit.length() == 0)\r
+ return "No unit defined";\r
+ \r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Resource configuration = graph.getPossibleObject(variable, L0.PartOf);\r
+ if(configuration == null)\r
+ return "Error, No Confiugration";\r
+ \r
+\r
+ SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+ SysdynModel sm = smm.getModel(graph, configuration);\r
+ \r
+ SysdynResource SR = SysdynResource.getInstance(graph);\r
+ for(Resource r : graph.getObjects(contexts.get(1), SR.Expression_equation)) {\r
+ graph.getValue(r);\r
+ }\r
+ \r
+ Object expr = sm.getMapping().get(contexts.get(1));\r
+ String result = ((IExpression)expr).matchUnits(graph, sm.getMapping());\r
+ return result;\r
+ }\r
+\r
+}
\ No newline at end of file
private String approximate(Double time, int index, SysdynDataSet dataset) {\r
\r
// time out of datasets range\r
- if(time > dataset.times[dataset.times.length - 1] ||\r
+ if(dataset.times.length == 0 || time > dataset.times[dataset.times.length - 1] ||\r
time < dataset.times[0]) {\r
return "---";\r
}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn;\r
+\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.ParseException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.UnitParser;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult;\r
+\r
+public class TestParser {\r
+ \r
+ /**\r
+ * @param args\r
+ */\r
+ public static void main(String[] args) {\r
+\r
+ HashMap<String, String> units = new HashMap<String, String>();\r
+ \r
+ doScenario(scenario1(units), units);\r
+ doScenario(scenario2(units), units);\r
+ doScenario(scenario3(units), units);\r
+ doScenario(scenario4(units), units);\r
+ doScenario(scenario5(units), units);\r
+ doScenario(scenario6(units), units);\r
+ doScenario(scenario7(units), units);\r
+ doScenario(scenario8(units), units);\r
+ doScenario(scenario9(units), units);\r
+ doScenario(scenario10(units), units);\r
+ doScenario(scenario11(units), units);\r
+ doScenario(scenario12(units), units);\r
+ doScenario(scenario13(units), units);\r
+\r
+ }\r
+ \r
+ private static void doScenario(String expression, HashMap<String, String> units) {\r
+ System.out.println("-----------------------------------");\r
+ System.out.println("Expression: " + expression);\r
+ System.out.println("Units: ");\r
+ for(String key : units.keySet()) {\r
+ System.out.println(" " + key + " -> " + units.get(key));\r
+ }\r
+ StringReader sr = new StringReader(expression);\r
+ UnitParser parser = new UnitParser(sr);\r
+ try {\r
+ UnitCheckingNode node = (UnitCheckingNode) parser.expr();\r
+ \r
+ try {\r
+ UnitResult u = node.getUnits(units);\r
+ System.out.println("Result: " + u.getCleanFullUnit());\r
+ } catch (UnitCheckingException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+// node.dump("");\r
+ } catch (ParseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ private static String scenario1(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ units.put("c", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("a*b*c");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario2(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ units.put("c", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("a+b+c");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario3(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ units.put("c", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("a/b+b/c");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario4(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ units.put("c", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("if a == b then a+b else b + c + a");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario5(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "s");\r
+ units.put("c", "m");\r
+ units.put("d", "s");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+// sb.append("a / b + (c*a)/(b*a)");\r
+ sb.append("c/(b*a)");\r
+\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario6(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "s");\r
+ units.put("c", "m");\r
+ units.put("d", "m/s");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("if a > c then c*a/b else a*d");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario7(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m/s");\r
+ units.put("b.e", "s");\r
+ units.put("c", "m");\r
+ units.put("d", "s");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("a[1] + c[1] / b.e[1]");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario8(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "s");\r
+ units.put("c", "s*m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("c + {a[i] * b[i] for i in 1:3}");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario9(HashMap<String, String> units) {\r
+ units.clear();\r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("1+a+1+b");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario10(HashMap<String, String> units) {\r
+ units.clear();\r
+ units.put("a", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("1*a*1*a");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario11(HashMap<String, String> units) {\r
+ units.clear();\r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("-a+b");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario12(HashMap<String, String> units) {\r
+ units.clear();\r
+ units.put("a", "m");\r
+ units.put("b", "s");\r
+ units.put("c", "m/s");\r
+\r
+\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("1/a/b + 1/c");\r
+ return sb.toString();\r
+ }\r
+ \r
+ private static String scenario13(HashMap<String, String> units) {\r
+ units.clear();\r
+ \r
+ units.put("a", "m");\r
+ units.put("b", "m");\r
+ units.put("c", "m");\r
+ units.put("d", "s");\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("(a/b+b/c)/d");\r
+ return sb.toString();\r
+ }\r
+ \r
+}\r
+\r
+\r
*/\r
public synchronized boolean update(ReadGraph graph) throws DatabaseException {\r
if(mapping.isDomainModified()) {\r
- \r
-\r
- \r
try {\r
Collection<Object> updated = mapping.updateRange(graph);\r
\r
}\r
\r
if(units != null && units.length() > 0)\r
- graph.claimLiteral(variable, sr.HasUnit, units);\r
+ graph.claimLiteral(variable, sr.Variable_unit, units);\r
if(comments != null && comments.length() > 0)\r
graph.claimLiteral(variable, l0.HasDescription, comments);\r
if(rangeStart != null)\r
void equation_section() : {\r
} {\r
// [ initial ] equation { equation ";" }\r
- ( "initial" )? "equation" ( equation() ";" )*\r
+ ( "initial" )? "equation" ( LOOKAHEAD(2) equation() ";" )*\r
}\r
\r
void algorithm_section() : {\r
// [= expression]\r
if(variability == Variability.PARAMETER || variability == Variability.CONSTANT) {\r
// parameters and constants are guaranteed to have only one expression\r
- String equation = FormatUtils.formatExpressionForModelica(this, getExpressions().get(0).getExpression(this));\r
+ String equation = FormatUtils.formatExpressionForModelica(this, getExpressions().get(0).getExpression());\r
sb.append(" = " + equation);\r
}\r
\r
if(getExpressions() != null) {\r
String addition;\r
for(IExpression e : getExpressions()) {\r
- addition = e.getDeclarationAddition(this);\r
+ addition = e.getDeclarationAddition();\r
if(addition != null)\r
sb.append(addition);\r
}\r
StringBuilder sb = new StringBuilder(); \r
\r
for(IExpression expression : getExpressions()) {\r
- String initialEquation = expression.getInitialEquation(this);\r
+ String initialEquation = expression.getInitialEquation();\r
if(initialEquation != null)\r
sb.append(initialEquation);\r
}\r
if(firstExpression == null)\r
return null;\r
else\r
- return firstExpression.getEquation(this);\r
+ return firstExpression.getEquation();\r
} else {\r
// ARRAY variable. Create all equations for the variable\r
StringBuilder sb = new StringBuilder(); \r
for(IExpression expression : expressions) {\r
- sb.append(expression.getEquation(this));\r
+ sb.append(expression.getEquation());\r
}\r
return sb.toString();\r
}\r
} else {\r
// Start parameter is used. Parameter guarantees that there is only one expression.\r
StockExpression e = (StockExpression)getExpressions().get(0);\r
- String initialEquation = e.getExpression(this);\r
+ String initialEquation = e.getExpression();\r
initialEquation = SheetFormatUtils.reformatSheetReferences(this, initialEquation);\r
\r
if(getArrayIndexes() != null && !getArrayIndexes().isEmpty())\r
getName() + \r
getRange() + \r
"(" + \r
- (e.getStartValue(this) != null ? each : "") + \r
+ (e.getStartValue() != null ? each : "") + \r
" start=" + \r
initialEquation + \r
", " + \r
\r
org.simantics.sysdyn.representation.expressions.IExpression ie = expressions.get(0);\r
\r
- String expression = ie.getExpression(variable);\r
+ String expression = ie.getExpression();\r
\r
return getVariability(variable, expression, allowVariableReferences, configuration);\r
}\r
@RelatedValue(SysdynResource.URIs.Variable_variability)\r
protected String variability;\r
\r
+ @RelatedValue(SysdynResource.URIs.Variable_unit)\r
+ protected String unit;\r
+ \r
/**\r
* Return the variability of this variable (Used in practice only with Input variables)\r
* @return Variability\r
return this.expressions;\r
}\r
\r
+ /**\r
+ * \r
+ * @return Units of this variable\r
+ */\r
+ public String getUnit() {\r
+ return this.unit;\r
+ }\r
+ \r
}\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
\r
/**\r
* Represents a constant expression\r
private String equation;\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return equation;\r
}\r
}\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.Variability;\r
-import org.simantics.sysdyn.representation.Variable;\r
import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
private String equation;\r
\r
@Override\r
- public String getDeclarationAddition(IndependentVariable variable) {\r
+ public String getDeclarationAddition() {\r
\r
- String delayTime = FormatUtils.formatExpressionForModelica(variable, this.delayTime);\r
- String initialValue = FormatUtils.formatExpressionForModelica(variable, this.initialValue);\r
- Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, delayTime);\r
+ String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime);\r
+ String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
+ Variability delayTimeVariability = Variability.getVariability((IndependentVariable)parent, delayTime);\r
Variability initialVariability = Variability.CONTINUOUS;\r
if(initialValue != null && initialValue.length() > 0) {\r
/*\r
* By default, initial value variability is continuous.\r
* If initial value has been set, it can be some other. \r
*/\r
- initialVariability = Variability.getVariability(variable, initialValue);\r
+ initialVariability = Variability.getVariability(parent, initialValue);\r
}\r
\r
\r
StringBuilder declaration = new StringBuilder();\r
\r
- String range = variable.getRange();\r
+ String range = parent.getRange();\r
\r
// Delay declaration\r
- declaration.append(" " + variable.getName() + "_delayClass " + variable.getName() + "_delayClass_instance");\r
+ declaration.append(" " + parent.getName() + "_delayClass " + parent.getName() + "_delayClass_instance");\r
\r
// Change enumeration sizes from the delay class. Supports overridden enumerations in modules.\r
if(range.length() > 0 || !initialVariability.equals(Variability.CONTINUOUS) || !delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
declaration.append(";\n");\r
\r
// Write the delay class\r
- declaration.append(getDelayClass(variable, range, order));\r
+ declaration.append(getDelayClass(range, order));\r
return declaration.toString();\r
}\r
\r
* @param n Order of the delay\r
* @return\r
*/\r
- private String getDelayClass(Variable variable, String range, int n) {\r
+ private String getDelayClass(String range, int n) {\r
StringBuilder sb = new StringBuilder();\r
\r
- sb.append("class " + variable.getName() + "_delayClass\n");\r
+ sb.append("class " + parent.getName() + "_delayClass\n");\r
\r
// Enumeration sizes as parameters. Sizes correspond the enumeration sizes of variable\r
if(range.length() > 0) {\r
}\r
}\r
\r
- String dt = FormatUtils.formatExpressionForModelica(variable,delayTime);\r
- Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, dt);\r
+ String dt = FormatUtils.formatExpressionForModelica(parent,delayTime);\r
+ Variability delayTimeVariability = Variability.getVariability(parent, dt);\r
if(!delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
// Auxiliary variable\r
sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " DL = delayTime/" + n + ";\n");\r
\r
// Get initial value variability\r
Variability initialValueVariability = Variability.CONTINUOUS;\r
- String initEquation = FormatUtils.formatExpressionForModelica(variable, this.initialValue);\r
+ String initEquation = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
if(initialValue != null && initialValue.length() > 0) {\r
- initialValueVariability = Variability.getVariability((IndependentVariable)variable, initEquation);\r
+ initialValueVariability = Variability.getVariability(parent, initEquation);\r
}\r
\r
// Declare initial value (continuous or other)\r
sb.append("\tdelay" + i + " = LV" + i + " " + (range.isEmpty() ? "/" : "./") + "DL;\n");\r
}\r
\r
- sb.append("end " + variable.getName() + "_delayClass;\n");\r
+ sb.append("end " + parent.getName() + "_delayClass;\n");\r
return sb.toString();\r
}\r
\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
+ public String getEquation() {\r
StringBuilder sb = new StringBuilder();\r
\r
- String equation = FormatUtils.formatExpressionForModelica(variable, this.equation);\r
- String delayTime = FormatUtils.formatExpressionForModelica(variable, this.delayTime);\r
- String initialValue = FormatUtils.formatExpressionForModelica(variable, this.initialValue);\r
+ String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
+ String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime);\r
+ String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue);\r
\r
// First "valve" in the delay\r
- sb.append(" " + variable.getName() + "_delayClass_instance.delay0 = " + equation + ";\n");\r
+ sb.append(" " + parent.getName() + "_delayClass_instance.delay0 = " + equation + ";\n");\r
\r
// Delay time (if continuous)\r
- Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, delayTime);\r
+ Variability delayTimeVariability = Variability.getVariability(parent, delayTime);\r
if(delayTimeVariability.equals(Variability.CONTINUOUS)) {\r
- sb.append(" " + variable.getName() + "_delayClass_instance.delayTime = " + delayTime + ";\n");\r
+ sb.append(" " + parent.getName() + "_delayClass_instance.delayTime = " + delayTime + ";\n");\r
}\r
\r
// Initial value\r
if(initialValue == null || initialValue.length() == 0) {\r
// No initial value set, use delay0 (the first "valve")\r
- sb.append(" " + variable.getName() + "_delayClass_instance.initialValue = " + variable.getName() + "_delayClass_instance.delay0;\n");\r
+ sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + parent.getName() + "_delayClass_instance.delay0;\n");\r
} else {\r
// Continuous initial value\r
- Variability initialVariability = Variability.getVariability(variable, initialValue);\r
+ Variability initialVariability = Variability.getVariability(parent, initialValue);\r
if(initialVariability.equals(Variability.CONTINUOUS)) {\r
- sb.append(" " + variable.getName() + "_delayClass_instance.initialValue = " + initialValue + ";\n");\r
+ sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + initialValue + ";\n");\r
}\r
}\r
\r
// The value of the actual variable\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
- sb.append(" " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + variable.getName() + "_delayClass_instance.delay" + order + ";\n");\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
+ sb.append(" " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + parent.getName() + "_delayClass_instance.delay" + order + ";\n");\r
return sb.toString();\r
}\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return "This + is + not + a + parameter + at + any + time";\r
}\r
\r
*******************************************************************************/\r
package org.simantics.sysdyn.representation.expressions;\r
\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.objmap.IMapping;\r
+import org.simantics.objmap.annotations.RelatedElement;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.utils.UnitUtils;\r
\r
/**\r
* Abstract class for any expression\r
\r
@RelatedValue(SysdynResource.URIs.Expression_arrayRange)\r
private String range;\r
+ \r
+ @RelatedElement(Layer0.URIs.PartOf)\r
+ protected IndependentVariable parent;\r
\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
+ public String getEquation() {\r
return null;\r
}\r
\r
@Override\r
- public String getInitialEquation(IndependentVariable variable) {\r
+ public String getInitialEquation() {\r
return null;\r
}\r
\r
@Override\r
- public String getDeclarationAddition(IndependentVariable variable) {\r
+ public String getDeclarationAddition() {\r
return null;\r
}\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return null;\r
}\r
\r
return range;\r
}\r
\r
+ @Override\r
+ public String matchUnits() {\r
+ return UnitUtils.matchUnits(null, null, parent, getExpression());\r
+ }\r
+ \r
+ @Override\r
+ public String matchUnits(ReadGraph graph, IMapping mapping) {\r
+ return UnitUtils.matchUnits(graph, mapping, parent, getExpression());\r
+ }\r
}\r
*******************************************************************************/\r
package org.simantics.sysdyn.representation.expressions;\r
\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.objmap.IMapping;\r
+\r
\r
/**\r
* Interface for all expressions in System Dynamics models\r
* @param variable Declared independent variable\r
* @return additions or null\r
*/\r
- String getDeclarationAddition(IndependentVariable variable);\r
+ String getDeclarationAddition();\r
\r
/**\r
* Initial value for this variable and expression\r
* @param variable IndependentVariable\r
* @return initial value or null\r
*/\r
- String getInitialEquation(IndependentVariable variable);\r
+ String getInitialEquation();\r
\r
/**\r
* Get the actual equation of this expression\r
* @param variable IndependentVariable\r
* @return equation or null\r
*/\r
- String getEquation(IndependentVariable variable);\r
+ String getEquation();\r
\r
/**\r
* Get the range of this expression\r
* @param variable\r
* @return\r
*/\r
- String getExpression(IndependentVariable variable);\r
-\r
+ String getExpression();\r
+ \r
+ \r
+ /**\r
+ * Match the units of this expression to units of its variable\r
+ * @return null if match, Error message otherwise\r
+ */\r
+ String matchUnits();\r
+ \r
+ /**\r
+ * Match the units of this expression to units of its variable. \r
+ * \r
+ * Requests units of referred variables for request listening\r
+ * @param graph ReadGraph\r
+ * @param mapping ObjMap mapping\r
+ * @return null if match, ERror message otherwise\r
+ */\r
+ String matchUnits(ReadGraph graph, IMapping mapping);\r
}\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
private String equation;\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return equation;\r
}\r
\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
- String equation = FormatUtils.formatExpressionForModelica(variable, this.equation);\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
- return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
+ public String getEquation() {\r
+ String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
+ return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
}\r
\r
}\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
\r
/**\r
private String equation;\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return equation + " /* Actual value read from init file */";\r
}\r
\r
@Override\r
- public String getDeclarationAddition(IndependentVariable variable) {\r
+ public String getDeclarationAddition() {\r
return ""; \r
}\r
\r
* Used when the expression is a part of an array variable. Then it is like a normal auxiliary.\r
*/\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
- return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
+ public String getEquation() {\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
+ return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n";\r
};\r
\r
public Double getValue() {\r
import org.simantics.sysdyn.representation.Book;\r
import org.simantics.sysdyn.representation.Enumeration;\r
import org.simantics.sysdyn.representation.IElement;\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.Sheet;\r
import org.simantics.sysdyn.representation.Stock;\r
import org.simantics.sysdyn.representation.Valve;\r
private String initialEquation;\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return initialEquation;\r
}\r
\r
\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
+ public String getEquation() {\r
\r
// Build range e.g. Stock[2,3]\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
\r
// Stock equation is always der(Stock)\r
StringBuilder b = new StringBuilder();\r
b.append(" der(")\r
- .append(variable.getName() + range)\r
+ .append(parent.getName() + range)\r
.append(") =");\r
\r
// Stock equation is formed automatically using incoming and outgoing flows (actually the nearest valves in those flows)\r
- ArrayList<Valve> incoming = ((Stock)variable).getIncomingValves();\r
- ArrayList<Valve> outgoing = ((Stock)variable).getOutgoingValves();\r
+ ArrayList<Valve> incoming = ((Stock)parent).getIncomingValves();\r
+ ArrayList<Valve> outgoing = ((Stock)parent).getOutgoingValves();\r
if(incoming.isEmpty() && outgoing.isEmpty()) {\r
// No connections, add 0 for each array index if any.\r
- ArrayList<Enumeration> enumerations = variable.getArrayIndexes();\r
+ ArrayList<Enumeration> enumerations = parent.getArrayIndexes();\r
if(enumerations == null || enumerations.isEmpty()) {\r
b.append(" 0.0");\r
} else {\r
* Check whether to use fixed=true and start=... in Modelica code\r
* @return\r
*/\r
- private boolean useStartValue(IndependentVariable variable) {\r
+ private boolean useStartValue() {\r
// If no variables are used in the equation, start value is used\r
\r
// First the equation is formatted and parsed\r
- String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation);\r
+ String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation);\r
ExpressionParser parser = new ExpressionParser(new StringReader(equation));\r
try {\r
parser.expr();\r
// We only need the first element to know that it is a Sheet (SheetName.CellOrRange)\r
reference = reference.split("\\.")[0]; \r
found = false;\r
- for(IElement element : variable.getParentConfiguration().getElements()) {\r
+ for(IElement element : parent.getParentConfiguration().getElements()) {\r
if(element instanceof Book) {\r
for(Sheet sheet : ((Book)element).getSheets()) {\r
if(reference.equals(sheet.getName())) {\r
}\r
\r
@Override\r
- public String getInitialEquation(IndependentVariable variable) {\r
+ public String getInitialEquation() {\r
// if start value is used, no initial equation is returned\r
- if(useStartValue(variable))\r
+ if(useStartValue())\r
return null;\r
// format the initial equation for modelica execution \r
- String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation, false);\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
+ String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation, false);\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
if(range == null)\r
range = "";\r
- return " " + variable.getName() + range + " = " + equation + ";\n";\r
+ return " " + parent.getName() + range + " = " + equation + ";\n";\r
}\r
\r
\r
* @param variable\r
* @return Double representing the initial equation or null if initial equation is not a double\r
*/\r
- public Double getStartValue(IndependentVariable variable) {\r
+ public Double getStartValue() {\r
Double value = null;\r
- ArrayList<IExpression> expressions = variable.getExpressions();\r
+ ArrayList<IExpression> expressions = parent.getExpressions();\r
if(expressions.size() == 1) {\r
IExpression e = expressions.get(0);\r
- if(e.getInitialEquation(variable) == null) {\r
+ if(e.getInitialEquation() == null) {\r
try {\r
value = Double.parseDouble(initialEquation);\r
} catch(NumberFormatException e1) {\r
import org.simantics.objmap.annotations.GraphType;\r
import org.simantics.objmap.annotations.RelatedValue;\r
import org.simantics.sysdyn.SysdynResource;\r
-import org.simantics.sysdyn.representation.IndependentVariable;\r
import org.simantics.sysdyn.representation.utils.FormatUtils;\r
import org.simantics.sysdyn.representation.utils.IndexUtils;\r
import org.simantics.sysdyn.representation.utils.SheetFormatUtils;\r
private String equation;\r
\r
@Override\r
- public String getEquation(IndependentVariable variable) {\r
- String equation = FormatUtils.formatExpressionForModelica(variable, this.equation);\r
- String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange());\r
+ public String getEquation() {\r
+ String equation = FormatUtils.formatExpressionForModelica(parent, this.equation);\r
+ String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange());\r
\r
return \r
- " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(variable, lookupTable) + ");\n";\r
+ " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(parent, lookupTable) + ");\n";\r
}\r
\r
@Override\r
- public String getExpression(IndependentVariable variable) {\r
+ public String getExpression() {\r
return "interpolate(" + equation + ", " + lookupTable + ")";\r
}\r
\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.representation.utils;\r
+\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.objmap.IMapping;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Module;\r
+import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.unitParser.ParseException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.UnitParser;\r
+import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult;\r
+\r
+public class UnitUtils {\r
+ \r
+ public static String matchUnits(ReadGraph graph, IMapping mapping, Variable variable, String expression) {\r
+ if(variable.getUnit() == null)\r
+ return "Unit not defined for " + variable.getName();\r
+ try {\r
+ \r
+ StringReader rightReader = new StringReader(expression);\r
+ UnitParser rightParser = new UnitParser(rightReader);\r
+ UnitCheckingNode right = (UnitCheckingNode) rightParser.expr();\r
+ rightReader.close();\r
+ Set<String> components = findComponents(right);\r
+ HashMap<String, String> units = findUnits(graph, mapping, variable, components);\r
+ \r
+ StringReader leftReader = new StringReader(variable.getUnit());\r
+ UnitParser leftParser = new UnitParser(leftReader);\r
+ UnitCheckingNode left = (UnitCheckingNode) leftParser.expr();\r
+ leftReader.close();\r
+ \r
+ try {\r
+ UnitResult rightUnits = right.getUnits(units);\r
+ UnitResult leftUnits = left.getUnits(null);\r
+ \r
+ if(!rightUnits.equals(leftUnits))\r
+ return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit();\r
+ } catch (UnitCheckingException e) {\r
+ return e.getMessage();\r
+ }\r
+ \r
+// node.dump("");\r
+ } catch (ParseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ return null;\r
+ }\r
+ \r
+ \r
+ private static HashMap<String, String> findUnits(ReadGraph graph, IMapping mapping, Variable variable, Set<String> components) {\r
+ HashMap<String, String> units = new HashMap<String, String>();\r
+ Configuration configuration = variable.getParentConfiguration();\r
+ for(String component : components) {\r
+ Variable var = getElement(configuration, component);\r
+ if(var != null) {\r
+ \r
+ // Support listening, if graph and mapping exists\r
+ if(graph != null && mapping != null) {\r
+ Resource varResource = mapping.inverseGet(var);\r
+ if(varResource != null) {\r
+ try {\r
+ graph.getPossibleRelatedValue(varResource, SysdynResource.getInstance(graph).Variable_unit);\r
+ } catch (ManyObjectsForFunctionalRelationException e) {\r
+ e.printStackTrace();\r
+ } catch (ServiceException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ \r
+ String unit = var.getUnit();\r
+ if(unit != null) {\r
+ units.put(component, unit);\r
+ }\r
+ }\r
+ }\r
+ \r
+ \r
+ \r
+ return units;\r
+ }\r
+ \r
+ private static Variable getElement(Configuration configuration, String name) {\r
+ String[] elements = name.split("\\.");\r
+ String element = elements[0];\r
+ for(IElement e : configuration.getElements()) {\r
+ if(e instanceof Variable) {\r
+ Variable var = (Variable)e;\r
+ if(var.getName().equals(element))\r
+ return var;\r
+ } else if(e instanceof Module && elements.length > 1) {\r
+ Module mod = (Module)e;\r
+ if(mod.getName().equals(element)) {\r
+ return getElement(mod.getType().getConfiguration(), name.substring(name.indexOf(".") + 1));\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ private static Set<String> findComponents(UnitCheckingNode node) {\r
+ HashSet<String> components = new HashSet<String>();\r
+ addComponents(node, components);\r
+ return components;\r
+ \r
+ }\r
+ \r
+ private static void addComponents(UnitCheckingNode node, HashSet<String> components) {\r
+ if(node instanceof ComponentReferenceFull) {\r
+ components.add(node.printNode());\r
+ } else {\r
+ for(int i = 0; i < node.jjtGetNumChildren(); i++) {\r
+ addComponents((UnitCheckingNode)node.jjtGetChild(i), components);\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser;\r
+\r
+public class UnitCheckingException extends Exception {\r
+ public UnitCheckingException(String string) {\r
+ super(string);\r
+ }\r
+\r
+ private static final long serialVersionUID = -5828012051088095625L;\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult;\r
+\r
+\r
+public class UnitCheckingNode extends SimpleNode {\r
+\r
+ public UnitCheckingNode(int id) {\r
+ super(id);\r
+ }\r
+\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException{\r
+ UnitResult result = new UnitResult();\r
+\r
+ if(jjtGetNumChildren() == 0){\r
+ String node = printNode();\r
+ result.append(node);\r
+ } else {\r
+ for(UnitCheckingNode node : getChildren()) {\r
+ result.appendResult(node.getUnits(units));\r
+ }\r
+ }\r
+ return result; \r
+ }\r
+ \r
+ protected ArrayList<UnitCheckingNode> getChildren() {\r
+ ArrayList<UnitCheckingNode> children = new ArrayList<UnitCheckingNode>();\r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ children.add((UnitCheckingNode)jjtGetChild(i));\r
+ }\r
+ return children;\r
+ }\r
+\r
+\r
+ public String printNode() {\r
+ StringBuilder sb = new StringBuilder();\r
+ Token token = jjtGetFirstToken();\r
+ sb.append(token.image);\r
+\r
+ while(token != null && !token.equals(jjtGetLastToken())) {\r
+ token = token.next;\r
+ sb.append(token.image);\r
+ }\r
+\r
+ return sb.toString();\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser;\r
+\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.nodes.AddOp;\r
+import org.simantics.sysdyn.unitParser.nodes.Arithmetic;\r
+import org.simantics.sysdyn.unitParser.nodes.ComponentIdentity;\r
+import org.simantics.sysdyn.unitParser.nodes.ComponentReference;\r
+import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull;\r
+import org.simantics.sysdyn.unitParser.nodes.Condition;\r
+import org.simantics.sysdyn.unitParser.nodes.Divide;\r
+import org.simantics.sysdyn.unitParser.nodes.ForIndex;\r
+import org.simantics.sysdyn.unitParser.nodes.IfThenElse;\r
+import org.simantics.sysdyn.unitParser.nodes.Multiplication;\r
+import org.simantics.sysdyn.unitParser.nodes.RelOp;\r
+import org.simantics.sysdyn.unitParser.nodes.Relation;\r
+import org.simantics.sysdyn.unitParser.nodes.Term;\r
+import org.simantics.sysdyn.unitParser.nodes.Value;\r
+\r
+public class UnitCheckingNodeFactory {\r
+ \r
+ private static HashMap<String, Class<?>> constructors = new HashMap<String, Class<?>>();\r
+ \r
+ static {\r
+ constructors.put("relation", Relation.class);\r
+ constructors.put("term", Term.class);\r
+ constructors.put("arithmetic_expression", Arithmetic.class);\r
+ constructors.put("ifthenelse", IfThenElse.class);\r
+ \r
+ constructors.put("component_reference_full", ComponentReferenceFull.class);\r
+ constructors.put("value", Value.class);\r
+\r
+\r
+ constructors.put("divide", Divide.class);\r
+ constructors.put("multiplication", Multiplication.class);\r
+ constructors.put("add_op", AddOp.class);\r
+ constructors.put("rel_op", RelOp.class);\r
+\r
+ \r
+ \r
+ constructors.put("component_reference", ComponentReference.class);\r
+ constructors.put("component_identity", ComponentIdentity.class);\r
+ constructors.put("condition", Condition.class);\r
+ constructors.put("for_index", ForIndex.class);\r
+ \r
+ }\r
+ \r
+ private static Class<?> getConstructor(int id) {\r
+ String name = UnitParserTreeConstants.jjtNodeName[id];\r
+ Class<?> constructor = constructors.get(name);\r
+ if(constructor == null)\r
+ return UnitCheckingNode.class;\r
+ else\r
+ return constructor;\r
+ }\r
+ \r
+ public static Node jjtCreate(int id) {\r
+ try {\r
+ return (Node) getConstructor(id).getConstructors()[0].newInstance(id);\r
+ } catch (IllegalArgumentException e) {\r
+ e.printStackTrace();\r
+ } catch (SecurityException e) {\r
+ e.printStackTrace();\r
+ } catch (InstantiationException e) {\r
+ e.printStackTrace();\r
+ } catch (IllegalAccessException e) {\r
+ e.printStackTrace();\r
+ } catch (InvocationTargetException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return null;\r
+ }\r
+ \r
+}\r
--- /dev/null
+options {\r
+ JDK_VERSION = "1.6";\r
+ STATIC = false;\r
+ TRACK_TOKENS=true;\r
+ NODE_CLASS="UnitCheckingNode";\r
+ NODE_FACTORY="UnitCheckingNodeFactory";\r
+}\r
+\r
+PARSER_BEGIN(UnitParser)\r
+package org.simantics.sysdyn.unitParser;\r
+\r
+public class UnitParser {\r
+\r
+ \r
+ \r
+}\r
+PARSER_END(UnitParser)\r
+\r
+/*** Lexer *********************************************************/\r
+\r
+SKIP:\r
+{ <WHITESPACE: " " | "\n" | "\r" | "\t" > \r
+| <COMMENT1: "/*" (~["*"] | "*" ~["/"])* "*/" > \r
+| <COMMENT2: "//" (~["\n"])* >\r
+}\r
+\r
+TOKEN:\r
+{\r
+"algorithm" | "discrete" | "false" | "model" | "redeclare"\r
+| "and" | "each" | "final" | "not" | "replaceable"\r
+| "annotation" | "else" | "flow" | "operator" | "return"\r
+|"assert" | "elseif" | "for" | "or" | "stream"\r
+| "block" | "elsewhen" | "function" | "outer" | "then"\r
+| "break" | "encapsulated" | "if" | "output" | "true"\r
+| "class" | "end" | "import" | "package" | "type"\r
+| "connect" | "enumeration" | "in" | "parameter" | "when"\r
+| "connector" | "equation" | /*"initial" |*/ "partial" | "while"\r
+| "constant" | "expandable" | "inner" | "protected" | "within"\r
+| "constrainedby" | "extends" | "input" | "public"\r
+| /*"der" |*/ "external" | "loop" | "record"\r
+| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | ","\r
+| "<" | "<=" | ">" | ">=" | "==" | "<>"\r
+| "+" | "-" | ".+" | ".-"\r
+| "*" | "/" | ".*" | "./"\r
+| "^" | ".^"\r
+| "=" | ":=" \r
+| <IDENT: ["a"-"z","A"-"Z","_"] (["a"-"z","A"-"Z","_","0"-"9"])* >\r
+| <STRING: "\"" (~["\"", "\\", "\n"] | "\\" ~["\n"])* "\"">\r
+ { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); }\r
+| <UNSIGNED_INTEGER: (["0"-"9"])+ >\r
+| <UNSIGNED_NUMBER: \r
+ ( <UNSIGNED_INTEGER> "." (<UNSIGNED_INTEGER>)? (["e","E"] <UNSIGNED_INTEGER>)?\r
+ | "." <UNSIGNED_INTEGER> (["e","E"] <UNSIGNED_INTEGER>)?\r
+ | <UNSIGNED_INTEGER> ["e","E"] <UNSIGNED_INTEGER>\r
+ ) >\r
+}\r
+\r
+/*** Parser ********************************************************/\r
+\r
+// https://javacc.dev.java.net/doc/javaccgrm.html\r
+// add_op -> add_op()\r
+// [ add_op ] -> ( add_op() )?\r
+// { add_op term } -> ( add_op() term() )*\r
+\r
+SimpleNode expr() : {\r
+} {\r
+ (simple_expression())? <EOF>\r
+ {\r
+ return jjtThis;\r
+ }\r
+ |\r
+ ifthenelse() <EOF>\r
+ {\r
+ return jjtThis;\r
+ }\r
+}\r
+\r
+void expression() : {\r
+} {\r
+ simple_expression()\r
+ | ifthenelse()\r
+}\r
+\r
+void ifthenelse() : {\r} {\r
+ "if" condition() "then" expression() ( "elseif" condition() "then" expression() )* "else" expression()\r
+}\r
+\r\r
+void condition() : {\r
+} {\r
+ expression()\r
+}\r \r \r
+\r
+void simple_expression() : {\r
+} {\r
+ logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )?\r
+} \r
+\r
+void logical_expression() : {\r
+} {\r
+ logical_term() ( "or" logical_term() )*\r
+} \r
+\r
+void logical_term() : {\r
+} {\r
+ logical_factor() ( "and" logical_factor() )*\r
+}\r
+\r
+void logical_factor() : {\r
+} {\r
+ ( "not" )? relation()\r
+}\r
+\r
+void relation() : {\r
+} {\r
+ arithmetic_expression() ( rel_op() arithmetic_expression() )?\r
+}\r
+\r
+void rel_op() : {\r
+} {\r
+ "<" | "<=" | ">" | ">=" | "==" | "<>"\r
+}\r
+\r
+void arithmetic_expression() : {\r
+} {\r
+ (add_op())? term() (add_op() term())*\r
+}\r
+\r
+void add_op() : {\r
+} {\r
+ "+" | "-" | ".+" | ".-"\r
+}\r
+\r
+void term() : {\r
+} {\r
+ factor() ( (multiplication() | divide()) factor() )*\r
+}\r
+\r
+void factor() : {\r
+} {\r
+ primary() ( "^" primary() | ".^" primary() )?\r
+}\r
+\r
+void multiplication() : {\r
+} {\r
+ "*" | ".*"\r
+}\r
+\r
+void divide() : {\r
+} {\r
+ "/" | "./"\r
+}\r
+\r
+void primary() : {\r
+} {\r
+ value()\r
+ | LOOKAHEAD( name() parenthesis_open() ) function_call() \r
+ | component_reference_full()\r
+ /*| "(" output_expression_list() ")"*/ // Not needed, replaced with following:\r
+ | parenthesis_expression()\r
+ | "[" expression_list() ( ";" expression_list() )* "]"\r
+ | "{" function_arguments() "}"\r
+ | "end"\r
+}\r
+\r
+void component_reference_full() : {\r
+} {\r
+ component_reference()\r
+}\r
+\r
+void function_call() : {\r
+} {\r
+ name() function_call_args()\r
+}\r
+\r
+void parenthesis_expression() : {\r} {\r parenthesis_open() expression() parenthesis_close()\r
+}\r
+\r
+void value() : {\r} {\r
+ <UNSIGNED_NUMBER>\r
+ | <UNSIGNED_INTEGER>\r
+ | <STRING>\r
+ | "false"\r
+ | "true"\r
+}\r \r
+\r
+void parenthesis_open() : {\r
+} {\r
+ "("\r
+}\r
+\r
+void parenthesis_close() : {\r
+} {\r
+ ")"\r
+}\r
+\r
+void name() : {\r
+} {\r
+ <IDENT> ( "." name() )?\r
+}\r
+\r
+void component_reference() : {\r
+} {\r
+ //IDENT [ array_subscripts ] [ "." component_reference ]\r
+ component_identity() ( array_subscripts() )? ( "." component_reference() )?\r
+}\r
+\r
+void component_identity() : {\r
+} {\r <IDENT>\r
+}\r \r
+\r
+void function_call_args() : {\r
+} {\r
+ parenthesis_open() ( function_arguments() )? parenthesis_close()\r
+}\r
+\r
+void function_arguments() : {\r
+} {\r
+ //expression [ "," function_arguments | for for_indices ]\r
+ //| named_arguments\r
+ LOOKAHEAD(2) named_argument() ( "," function_arguments() )?\r
+ | expression() ( "," function_arguments() | "for" for_indices() )?\r
+ \r
+}\r
+\r
+void for_indices() : {\r
+} {\r
+ //for_index {"," for_index}\r
+ for_index() ("," for_index())*\r
+}\r
+\r
+void for_index() : {\r
+} {\r
+ //IDENT [ in expression ]\r
+ <IDENT> ( "in" expression() )?\r
+}\r
+\r
+/* Removed by Teemu. Refactored in function_arguments)\r
+void named_arguments() : {\r
+} {\r
+ named_argument() ( "," named_arguments() )?\r
+}\r
+*/\r
+\r
+void named_argument() : {\r
+} { \r
+ <IDENT> "=" expression()\r
+}\r
+\r
+void output_expression_list() : {\r
+} {\r
+ ( expression() )? ( "," ( expression() )? )*\r
+}\r
+\r
+\r
+void expression_list() : {\r
+} {\r
+ expression() ( "," expression() )*\r
+}\r
+\r
+void array_subscripts() : {\r
+} {\r
+ "[" subscript() ( "," subscript() )* "]"\r
+}\r
+\r
+void subscript() : {\r
+} {\r ":"\r
+ | LOOKAHEAD( name() parenthesis_open() ) name() function_call_args()\r
+ | rangeIndex() ( ":" rangeIndex())?\r
+}\r
+\r
+void rangeIndex() : {\r
+} {\r <UNSIGNED_INTEGER>\r
+ | <IDENT>\r
+}\r \r
+\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class AddOp extends UnitCheckingNode {\r
+\r
+ public AddOp(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = super.getUnits(units);\r
+ result.setUnitType(UnitType.OPERATOR);\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Arithmetic extends UnitCheckingNode {\r
+\r
+ public Arithmetic(int id) {\r
+ super(id);\r
+ }\r
+\r
+\r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = new UnitResult();\r
+\r
+ UnitCheckingNode base = null;\r
+ UnitCheckingNode operator = null;\r
+ UnitCheckingNode candidateNode = null;\r
+\r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ candidateNode = ((UnitCheckingNode)jjtGetChild(i));\r
+ UnitResult candidateUnits = candidateNode.getUnits(units);\r
+ if(candidateUnits.getUnitType() == UnitType.OPERATOR || candidateUnits.getUnitType() == UnitType.ANY) {\r
+ result.setUnitType(candidateUnits.getUnitType());\r
+ continue;\r
+ } else if(base == null) {\r
+ base = ((UnitCheckingNode)jjtGetChild(i));\r
+ result.appendResult(base.getUnits(units));\r
+ continue;\r
+ } else {\r
+ operator = ((UnitCheckingNode)jjtGetChild(i-1));\r
+ if(!result.equals(candidateUnits)) {\r
+ throw new UnitCheckingException("Not equals exception: " +\r
+ base.printNode() + " [" + result.getCleanFullUnit() + "] " + operator.printNode() + " " +\r
+ candidateNode.printNode() + " [" + candidateUnits.getCleanFullUnit() + "]"\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ComponentIdentity extends UnitCheckingNode {\r
+\r
+ public ComponentIdentity(int id) {\r
+ super(id);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ComponentReference extends UnitCheckingNode {\r
+\r
+ public ComponentReference(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public String printNode() {\r
+ StringBuilder sb = new StringBuilder();\r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i);\r
+ if(node instanceof ComponentIdentity || node instanceof ComponentReference) {\r
+ if(sb.length() > 0)\r
+ sb.append(".");\r
+ sb.append(node.printNode());\r
+ }\r
+ }\r
+ return sb.toString();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.ParseException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.UnitParser;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ComponentReferenceFull extends UnitCheckingNode {\r
+\r
+ public ComponentReferenceFull(int id) {\r
+ super(id);\r
+ }\r
+\r
+ protected UnitResult parseUnits(String units) {\r
+ StringReader sr = new StringReader(units);\r
+ UnitParser parser = new UnitParser(sr);\r
+ try {\r
+ UnitCheckingNode node = (UnitCheckingNode) parser.expr();\r
+ return node.getUnits(null);\r
+ } catch (ParseException e) {\r
+ e.printStackTrace();\r
+ } catch (UnitCheckingException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ String node = printNode();\r
+ node = printNode();\r
+ if(units != null) {\r
+ if(!units.containsKey(node))\r
+ throw new UnitCheckingException("No units defined for " + node);\r
+ else {\r
+ return parseUnits(units.get(node));\r
+ }\r
+ } else {\r
+ UnitResult result = new UnitResult();\r
+ result.addDivident(node);\r
+ result.append(node);\r
+ return result; \r
+ }\r
+ }\r
+\r
+ @Override\r
+ public String printNode() {\r
+ StringBuilder sb = new StringBuilder();\r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i);\r
+ sb.append(node.printNode());\r
+ }\r
+ return sb.toString();\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Condition extends UnitCheckingNode {\r
+\r
+ public Condition(int id) {\r
+ super(id);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Divide extends UnitCheckingNode {\r
+\r
+ public Divide(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = super.getUnits(units);\r
+ result.setUnitType(UnitType.OPERATOR);\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ForIndex extends UnitCheckingNode {\r
+\r
+ public ForIndex(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ return new UnitResult();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class IfThenElse extends UnitCheckingNode {\r
+\r
+ public IfThenElse(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult base = null;\r
+ UnitCheckingNode baseNode = null;\r
+ UnitCheckingNode candidateNode = null;\r
+ \r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ candidateNode = ((UnitCheckingNode)jjtGetChild(i));\r
+ UnitResult candidateUnits = candidateNode.getUnits(units);\r
+ \r
+ if(!(candidateNode instanceof Condition)) {\r
+ \r
+ if(base == null) {\r
+ base = candidateUnits;\r
+ baseNode = candidateNode;\r
+ } else {\r
+ if(!base.equals(candidateUnits)) {\r
+ base.equals(candidateUnits);\r
+ throw new UnitCheckingException("Conditional results do not have same units: \n" +\r
+ printNode() + "\n" + \r
+ baseNode.printNode() + " [" + base.getFullUnit() + "] <-> " +\r
+ candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]"\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ }\r
+ \r
+ return base;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Multiplication extends UnitCheckingNode {\r
+\r
+ public Multiplication(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = super.getUnits(units);\r
+ result.setUnitType(UnitType.OPERATOR);\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class RelOp extends UnitCheckingNode {\r
+\r
+ public RelOp(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = super.getUnits(units);\r
+ result.setUnitType(UnitType.OPERATOR);\r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Relation extends UnitCheckingNode {\r
+\r
+ public Relation(int id) {\r
+ super(id);\r
+ }\r
+\r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = new UnitResult();\r
+ \r
+ UnitCheckingNode base = null;\r
+ UnitCheckingNode operator = null;\r
+ UnitCheckingNode candidateNode = null;\r
+ \r
+ base = ((UnitCheckingNode)jjtGetChild(0));\r
+ if(!(base instanceof Arithmetic) && jjtGetNumChildren() > 1)\r
+ base = ((UnitCheckingNode)jjtGetChild(1));\r
+ \r
+ if(base instanceof Arithmetic) {\r
+ result.appendResult(base.getUnits(units));\r
+\r
+ for(int i = 2; i < jjtGetNumChildren(); i = i + 2) {\r
+ candidateNode = ((UnitCheckingNode)jjtGetChild(i));\r
+\r
+ if(!(candidateNode instanceof Value)) {\r
+ operator = ((UnitCheckingNode)jjtGetChild(i-1));\r
+ UnitResult candidateUnits = candidateNode.getUnits(units);\r
+ if(!result.equals(candidateUnits)) {\r
+ result.equals(candidateUnits);\r
+ throw new UnitCheckingException("Not equals exception: " +\r
+ base.printNode() + " [" + result.getFullUnit() + "] " + operator.printNode() + " " +\r
+ candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]"\r
+ );\r
+ }\r
+ }\r
+\r
+ }\r
+ }\r
+ \r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Term extends UnitCheckingNode {\r
+\r
+ public Term(int id) {\r
+ super(id);\r
+ }\r
+ \r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = new UnitResult();\r
+ \r
+ UnitCheckingNode current = null;\r
+ UnitCheckingNode operator = null;\r
+ UnitCheckingNode base = null;\r
+ \r
+ for(int i = 0; i < jjtGetNumChildren(); i++) {\r
+ current = ((UnitCheckingNode)jjtGetChild(i));\r
+ UnitResult currentUnits = current.getUnits(units);\r
+\r
+ if(currentUnits.getUnitType() == UnitType.OPERATOR) {\r
+ continue;\r
+ } else if(base == null) {\r
+ base = current;\r
+ result.appendResult(currentUnits);\r
+ continue;\r
+ } else {\r
+ operator = ((UnitCheckingNode)jjtGetChild(i-1));\r
+\r
+ if(operator instanceof Multiplication) {\r
+ if(currentUnits.getUnitType() != UnitType.ANY) {\r
+ result.append(operator.printNode());\r
+ result.appendResult(currentUnits);\r
+ }\r
+ } else if(operator instanceof Divide){\r
+ result.append(operator.printNode());\r
+ result.addAllDividers(currentUnits.getDividers());\r
+ result.addAllDividers(currentUnits.getDividents());\r
+ result.setUnitType(currentUnits.getUnitType());\r
+ \r
+ if(currentUnits.getUnitType() == UnitType.ANY)\r
+ result.append("1");\r
+ else\r
+ result.append(currentUnits.getFullUnit());\r
+ }\r
+ }\r
+ }\r
+ \r
+ return result;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Iterator;\r
+\r
+/**\r
+ * Result of getUnits() request for Unit Parser nodes. \r
+ * \r
+ * Result is built of dividers and dividents. ( divident / divider )\r
+ * \r
+ * UnitType may provide information for handling this unit result\r
+ * \r
+ * fullUnit is the print of this unit in the order it is created.\r
+ * \r
+ * getCleanFullUnit reduces all unnecessary units and provides the most\r
+ * clean representation of the unit. ( e.g. m * s / m -> s )\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class UnitResult {\r
+ \r
+ public enum UnitType {NORMAL, ANY, DMNL, OPERATOR};\r
+ \r
+ private ArrayList<String> dividers = new ArrayList<String>();\r
+ private ArrayList<String> dividents = new ArrayList<String>();\r
+ private StringBuilder fullUnit = new StringBuilder();\r
+ private UnitType unitType = UnitType.NORMAL;\r
+ \r
+ public void appendResult(UnitResult result) {\r
+ addAllDividents(result.getDividents());\r
+ addAllDividers(result.getDividers());\r
+ append(result.getFullUnit());\r
+ setUnitType(result.getUnitType());\r
+ }\r
+ \r
+ public void addDivider(String divider) {\r
+ this.dividers.add(divider);\r
+ Collections.sort(this.dividers);\r
+ }\r
+ \r
+ public void addAllDividers(ArrayList<String> dividers) {\r
+ this.dividers.addAll(dividers);\r
+ Collections.sort(this.dividers);\r
+ }\r
+ \r
+ public void addDivident(String divident) {\r
+ this.dividents.add(divident);\r
+ Collections.sort(this.dividents);\r
+ }\r
+ \r
+ public void addAllDividents(ArrayList<String> dividents) {\r
+ this.dividents.addAll(dividents);\r
+ Collections.sort(this.dividents);\r
+ }\r
+ \r
+ public void append(String text) {\r
+ this.fullUnit.append(text);\r
+ }\r
+ \r
+ public ArrayList<String> getDividers() {\r
+ return this.dividers;\r
+ }\r
+ \r
+ public ArrayList<String> getDividents() {\r
+ return this.dividents;\r
+ }\r
+ \r
+ public String getFullUnit() {\r
+ return fullUnit.toString();\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Get clean representation of this unit. All redundant \r
+ * units are cleanend out and the unit is represented\r
+ * with max one '/' character.\r
+ * @return\r
+ */\r
+ public String getCleanFullUnit() {\r
+ if(dividers.size() == 0 && dividents.size() == 0)\r
+ return "";\r
+ \r
+ if(dividers.size() > 0 && dividents.size() == 0)\r
+ dividents.add("1");\r
+ \r
+ ArrayList<String> copyDividers1 = new ArrayList<String>(dividers);\r
+ ArrayList<String> copyDividents1 = new ArrayList<String>(dividents);\r
+ reduceUnitLists(dividents, copyDividents1, copyDividers1);\r
+ \r
+ StringBuilder sb = new StringBuilder();\r
+ Iterator<String> iterator = copyDividents1.iterator();\r
+ while(iterator.hasNext()) {\r
+ String s = iterator.next();\r
+ sb.append(s);\r
+ if(iterator.hasNext())\r
+ sb.append("*");\r
+ }\r
+ \r
+ if(copyDividers1.size() > 0) {\r
+ sb.append("/");\r
+ if(copyDividers1.size() > 1)\r
+ sb.append("(");\r
+ \r
+ iterator = copyDividers1.iterator();\r
+ while(iterator.hasNext()) {\r
+ String s = iterator.next();\r
+ sb.append(s);\r
+ if(iterator.hasNext())\r
+ sb.append("*");\r
+ }\r
+ \r
+ if(copyDividers1.size() > 1)\r
+ sb.append(")");\r
+ }\r
+ \r
+ return sb.toString();\r
+ }\r
+ \r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if(!(obj instanceof UnitResult))\r
+ return false;\r
+ \r
+ UnitResult other = (UnitResult)obj;\r
+ \r
+ if(getUnitType() == UnitType.ANY || other.getUnitType() == UnitType.ANY)\r
+ return true;\r
+ \r
+ ArrayList<String> copyDividers1 = new ArrayList<String>(dividers);\r
+ ArrayList<String> copyDividents1 = new ArrayList<String>(dividents);\r
+ reduceUnitLists(dividents, copyDividents1, copyDividers1);\r
+\r
+ ArrayList<String> copyDividers2 = new ArrayList<String>(other.dividers);\r
+ ArrayList<String> copyDividents2 = new ArrayList<String>(other.dividents); \r
+ reduceUnitLists(other.dividents, copyDividents2, copyDividers2);\r
+\r
+ if(copyDividents1.size() != copyDividents2.size())\r
+ return false;\r
+ if(copyDividers1.size() != copyDividers2.size())\r
+ return false;\r
+ \r
+ for(int i = 0; i < copyDividents1.size(); i++) {\r
+ String a = copyDividents1.get(i);\r
+ String b = copyDividents2.get(i);\r
+ if(!a.equals(b)) {\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ for(int i = 0; i < copyDividers1.size(); i++) {\r
+ String a = copyDividers1.get(i);\r
+ String b = copyDividers2.get(i);\r
+ if(!a.equals(b)) {\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ return true;\r
+ }\r
+ \r
+ public void reduceUnitLists(ArrayList<String> originalDividents, ArrayList<String> copyDividents, ArrayList<String> copyDividers) {\r
+ for(String s : originalDividents) {\r
+ if(copyDividers.contains(s)) {\r
+ copyDividers.remove(s);\r
+ copyDividents.remove(s);\r
+ }\r
+ }\r
+ \r
+ if(copyDividents.isEmpty())\r
+ copyDividents.add("1");\r
+ }\r
+\r
+ public UnitType getUnitType() {\r
+ return unitType;\r
+ }\r
+\r
+ public void setUnitType(UnitType unitType) {\r
+ this.unitType = unitType;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.unitParser.nodes;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.sysdyn.unitParser.UnitCheckingException;\r
+import org.simantics.sysdyn.unitParser.UnitCheckingNode;\r
+import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType;\r
+\r
+/**\r
+ * See UnitCheckingNodeFactory for mapping\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Value extends UnitCheckingNode {\r
+\r
+ public Value(int id) {\r
+ super(id);\r
+ }\r
+\r
+ @Override\r
+ public UnitResult getUnits(HashMap<String, String> units) throws UnitCheckingException {\r
+ UnitResult result = super.getUnits(units);\r
+ result.setUnitType(UnitType.ANY);\r
+ return result;\r
+ }\r
+}\r