From: lempinen Date: Mon, 29 Apr 2013 06:36:29 +0000 (+0000) Subject: Unit analysis for expressions. (refs #4093) X-Git-Tag: 1.8.1~320 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=8ea291d533f531506c805720caf1591a1e013197;p=simantics%2Fsysdyn.git Unit analysis for expressions. (refs #4093) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@27296 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index 6d1e0b6a..44425342 100644 Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ diff --git a/org.simantics.sysdyn.ontology/graph/Migration.pgraph b/org.simantics.sysdyn.ontology/graph/Migration.pgraph index 7d135469..c52fecbc 100644 --- a/org.simantics.sysdyn.ontology/graph/Migration.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Migration.pgraph @@ -119,6 +119,8 @@ FROM16TO17.SysdynChanges : L0.NamespaceMigrationStep @move "http://www.simantics.org/Sysdyn-1.1/" "HasHead" "Variable/HasHead" _ @move "http://www.simantics.org/Sysdyn-1.1/" "SharedModuleOntolofgy" "SharedModuleOntology" + _ + @move "http://www.simantics.org/Sysdyn-1.1/" "HasUnit" "Variable/unit" FROM16TO17.OrderedSetsToLists : L0.OrderedSetToListMigrationStep diff --git a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph index 76fd48dd..f04d001f 100644 --- a/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph @@ -137,10 +137,6 @@ SYSDYN.Variable + + + + + + + () { + + @Override + public Boolean perform(ReadGraph graph, Resource model) throws DatabaseException { + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource)); + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, IssueResource.getInstance(graph).IssueSource_active, Bindings.BOOLEAN); + return Boolean.TRUE.equals(result); + } + }); + + validateUnits.addSelectionListener(new SelectionListenerImpl(context){ + + @Override + public void apply(WriteGraph graph, Resource model) throws DatabaseException { + Resource unitIssueSource = graph.syncRequest( + new PossibleObjectWithType(model, + Layer0X.getInstance(graph).Activates, + SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource)); + IssueResource ISSUE = IssueResource.getInstance(graph); + Boolean result = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN); + if(result == null) + result = false; + graph.claimLiteral(unitIssueSource, ISSUE.IssueSource_active, Boolean.FALSE.equals(result)); + } + + }); + + // Scrolled composite settings sc.setContent(composite); sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java index eab753cb..358ee0d1 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java @@ -64,6 +64,8 @@ import org.simantics.db.request.Read; import org.simantics.db.service.VirtualGraphSupport; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo; import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes; import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType; @@ -529,7 +531,7 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { if (model != null) { Collection variables = graph.getObjects(model, l0.ConsistsOf); for(Resource v : variables) { - Object unit = graph.getPossibleRelatedValue(v, sr.HasUnit); + Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit); if (unit != null && !map.keySet().contains(unit)) { map.put((String)unit, (String)unit); @@ -545,7 +547,7 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { @Override public String perform(ReadGraph graph, final Resource input) throws DatabaseException { - String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HasUnit); + String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).Variable_unit); if(unit == null) return ""; else @@ -558,7 +560,14 @@ public class EquationTab extends LabelPropertyTabContributor implements Widget { @Override public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException { - graph.claimLiteral(input, SysdynResource.getInstance(graph).HasUnit, text); + graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit); + graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text); + + Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf); + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, conf); + sm.getMapping().domainModified(input); + sm.update(graph); } }); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java index b4d5521e..06a9e2bb 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java @@ -42,7 +42,7 @@ public class ModuleParameterOverrideUtils { public static String getParameterExpression(IndependentVariable variable) throws DatabaseException { String result = null; try { - result = variable.getExpressions().get(0).getExpression(variable); + result = variable.getExpressions().get(0).getExpression(); if(result.contains("/* Actual value read from init file */")) result = result.substring(0, result.indexOf("/* Actual value read from init file */")); } catch (NullPointerException e) { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java index c6a513d1..7682db35 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java @@ -199,11 +199,11 @@ public class ExpressionUtils { // Get model configuration SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession()); SysdynModel model = sdm.getModel(configuration); - try { - model.update(); - } catch (DatabaseException e1) { - e1.printStackTrace(); - } +// try { +// model.update(); +// } catch (DatabaseException e1) { +// e1.printStackTrace(); +// } Configuration conf = model.getConfiguration(); // Check variable references diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java index 60b4280d..8e4833b3 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java @@ -11,6 +11,7 @@ import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.Template; import org.simantics.document.DocumentResource; +import org.simantics.issues.ontology.IssueResource; import org.simantics.layer0.Layer0; import org.simantics.layer0.utils.direct.GraphUtils; import org.simantics.modeling.ModelingResources; @@ -95,7 +96,14 @@ public class ModelUtils { sr.Validations_Enumerations_EnumerationIssueSource, L0X.IsActivatedBy, model, l0.PartOf, model - ); + ); + + GraphUtils.create2(g, + sr.Validations_Units_UnitIssueSource, + L0X.IsActivatedBy, model, + l0.PartOf, model, + IssueResource.getInstance(g).IssueSource_active, false + ); Resource conf = GraphUtils.create2(g, sr.Configuration, diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtils.java index eee9b25d..d7fae469 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtils.java @@ -143,7 +143,7 @@ public class ImportUtils { final Resource project = SimanticsUI.getProject().get(); if(project == null) return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Import model: project not found", null); - beginTask(monitor, "Import model", 8); + beginTask(monitor, "Import model", 9); Activator.getDefault().getPreferenceStore().setValue(IMPORTMODELTPATH, (new File(path)).getParent()); @@ -192,6 +192,9 @@ public class ImportUtils { subTask(monitor, "Add enumeration issue source"); addEnumerationIssueSource(graph, ModelRoot); worked(monitor, 1); + subTask(monitor, "Add unit issue source"); + addUnitIssueSource(graph, ModelRoot); + worked(monitor, 1); subTask(monitor, "Add shadow profile"); addShadowProfile(graph, ModelRoot); worked(monitor, 1); @@ -203,6 +206,7 @@ public class ImportUtils { } + }); if(status != null) @@ -328,6 +332,22 @@ public class ImportUtils { } } + + private static void addUnitIssueSource(WriteGraph graph, Resource modelRoot) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + Collection unitIssueSources = graph.syncRequest(new ObjectsWithType(modelRoot, L0.ConsistsOf, sr.Validations_Units_UnitIssueSource)); + if(unitIssueSources.isEmpty()) { + GraphUtils.create2(graph, + sr.Validations_Units_UnitIssueSource, + L0X.IsActivatedBy, modelRoot, + L0.PartOf, modelRoot, + IssueResource.getInstance(graph).IssueSource_active, false + ); + } + } + private static void addShadowProfile(WriteGraph graph, Resource modelRoot) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); SysdynResource SR = SysdynResource.getInstance(graph); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java new file mode 100644 index 00000000..de8b9eee --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.validation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.simantics.db.Issue; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.issue.StandardIssue; +import org.simantics.db.common.utils.ListUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.issues.common.IssueUtils; +import org.simantics.layer0.Layer0; +import org.simantics.scl.reflection.annotations.SCLValue; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynModel; +import org.simantics.sysdyn.manager.SysdynModelManager; +import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.expressions.IExpression; + +public class UnitFunction { + + @SCLValue(type = "ReadGraph -> Resource -> [Issue]") + public static List unitValidator(ReadGraph graph, Resource independentVariable) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource SR = SysdynResource.getInstance(graph); + + + if(independentVariable == null) + return Collections.emptyList(); + + Resource configuration = graph.getPossibleObject(independentVariable, L0.PartOf); + if(configuration == null) + return Collections.emptyList(); + + // Make sure unit updates are listened to + Resource unitResource = graph.getPossibleObject(independentVariable, SR.Variable_unit); + String unit = graph.getPossibleRelatedValue(independentVariable, SR.Variable_unit); + if(unit == null || unit.trim().length() == 0) + return Collections.singletonList(new StandardIssue(SR.Validations_UnitWarning, independentVariable)); + + Resource expressionList = graph.getPossibleObject(independentVariable, SR.Variable_expressionList); + + if(expressionList == null) + return Collections.emptyList(); + + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + sm.getMapping().domainModified(independentVariable); + + sm.update(graph); + Object var = sm.getMapping().get(independentVariable); + + ArrayList issues = new ArrayList(); + + for(Resource expression : ListUtils.toList(graph, expressionList)) { + for(Resource r : graph.getObjects(expression, SR.Expression_equation)) { + graph.getValue(r); + } + + sm.getMapping().domainModified(expression); + sm.update(graph); + + Object expr = sm.getMapping().get(expression); + + if(expr != null && var != null && expr instanceof IExpression && var instanceof IndependentVariable) { + String result = ((IExpression)expr).matchUnits(graph, sm.getMapping()); + if(result != null) { + Issue issue = new StandardIssue(SR.Validations_UnitWarning, independentVariable, expression, unitResource); + issues.add(issue); + } + } + } + + return issues; + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> String") + public static String unitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException { + List contexts = IssueUtils.getContextsForProperty(graph, property); + + if(contexts.size() == 0) + return "Error, No contexts"; + + Resource variable = contexts.get(0); + String unit = graph.getPossibleRelatedValue(variable, SysdynResource.getInstance(graph).Variable_unit); + + if(unit == null || unit.length() == 0) + return "No unit defined"; + + Layer0 L0 = Layer0.getInstance(graph); + Resource configuration = graph.getPossibleObject(variable, L0.PartOf); + if(configuration == null) + return "Error, No Confiugration"; + + + SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession()); + SysdynModel sm = smm.getModel(graph, configuration); + + SysdynResource SR = SysdynResource.getInstance(graph); + for(Resource r : graph.getObjects(contexts.get(1), SR.Expression_equation)) { + graph.getValue(r); + } + + Object expr = sm.getMapping().get(contexts.get(1)); + String result = ((IExpression)expr).matchUnits(graph, sm.getMapping()); + return result; + } + +} \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java index 5cfca79e..049bcb80 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java @@ -296,7 +296,7 @@ public class ValueView extends ViewPart { private String approximate(Double time, int index, SysdynDataSet dataset) { // time out of datasets range - if(time > dataset.times[dataset.times.length - 1] || + if(dataset.times.length == 0 || time > dataset.times[dataset.times.length - 1] || time < dataset.times[0]) { return "---"; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java new file mode 100644 index 00000000..f12f8281 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/TestParser.java @@ -0,0 +1,230 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn; + +import java.io.StringReader; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.UnitResult; + +public class TestParser { + + /** + * @param args + */ + public static void main(String[] args) { + + HashMap units = new HashMap(); + + doScenario(scenario1(units), units); + doScenario(scenario2(units), units); + doScenario(scenario3(units), units); + doScenario(scenario4(units), units); + doScenario(scenario5(units), units); + doScenario(scenario6(units), units); + doScenario(scenario7(units), units); + doScenario(scenario8(units), units); + doScenario(scenario9(units), units); + doScenario(scenario10(units), units); + doScenario(scenario11(units), units); + doScenario(scenario12(units), units); + doScenario(scenario13(units), units); + + } + + private static void doScenario(String expression, HashMap units) { + System.out.println("-----------------------------------"); + System.out.println("Expression: " + expression); + System.out.println("Units: "); + for(String key : units.keySet()) { + System.out.println(" " + key + " -> " + units.get(key)); + } + StringReader sr = new StringReader(expression); + UnitParser parser = new UnitParser(sr); + try { + UnitCheckingNode node = (UnitCheckingNode) parser.expr(); + + try { + UnitResult u = node.getUnits(units); + System.out.println("Result: " + u.getCleanFullUnit()); + } catch (UnitCheckingException e) { + e.printStackTrace(); + } + +// node.dump(""); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + private static String scenario1(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a*b*c"); + return sb.toString(); + } + + private static String scenario2(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a+b+c"); + return sb.toString(); + } + + private static String scenario3(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("a/b+b/c"); + return sb.toString(); + } + + private static String scenario4(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("if a == b then a+b else b + c + a"); + return sb.toString(); + } + + private static String scenario5(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); +// sb.append("a / b + (c*a)/(b*a)"); + sb.append("c/(b*a)"); + + return sb.toString(); + } + + private static String scenario6(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m"); + units.put("d", "m/s"); + + StringBuilder sb = new StringBuilder(); + sb.append("if a > c then c*a/b else a*d"); + return sb.toString(); + } + + private static String scenario7(HashMap units) { + units.clear(); + + units.put("a", "m/s"); + units.put("b.e", "s"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); + sb.append("a[1] + c[1] / b.e[1]"); + return sb.toString(); + } + + private static String scenario8(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "s*m"); + + StringBuilder sb = new StringBuilder(); + sb.append("c + {a[i] * b[i] for i in 1:3}"); + return sb.toString(); + } + + private static String scenario9(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("1+a+1+b"); + return sb.toString(); + } + + private static String scenario10(HashMap units) { + units.clear(); + units.put("a", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("1*a*1*a"); + return sb.toString(); + } + + private static String scenario11(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "m"); + + StringBuilder sb = new StringBuilder(); + sb.append("-a+b"); + return sb.toString(); + } + + private static String scenario12(HashMap units) { + units.clear(); + units.put("a", "m"); + units.put("b", "s"); + units.put("c", "m/s"); + + + StringBuilder sb = new StringBuilder(); + sb.append("1/a/b + 1/c"); + return sb.toString(); + } + + private static String scenario13(HashMap units) { + units.clear(); + + units.put("a", "m"); + units.put("b", "m"); + units.put("c", "m"); + units.put("d", "s"); + + StringBuilder sb = new StringBuilder(); + sb.append("(a/b+b/c)/d"); + return sb.toString(); + } + +} + + diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java index 29f9fc72..91378b2b 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java @@ -272,9 +272,6 @@ public class SysdynModel implements IMappingListener, IModel, VariableSubscripti */ public synchronized boolean update(ReadGraph graph) throws DatabaseException { if(mapping.isDomainModified()) { - - - try { Collection updated = mapping.updateRange(graph); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java index ad27b79b..f2fc13bf 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/mdlImport/mdlElements/Variable.java @@ -81,7 +81,7 @@ public abstract class Variable extends Element { } if(units != null && units.length() > 0) - graph.claimLiteral(variable, sr.HasUnit, units); + graph.claimLiteral(variable, sr.Variable_unit, units); if(comments != null && comments.length() > 0) graph.claimLiteral(variable, l0.HasDescription, comments); if(rangeStart != null) diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj index 8cf3a5b7..fe483fe1 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelParser/ModelicaParser.jj @@ -396,7 +396,7 @@ void component_declaration1() : { void equation_section() : { } { // [ initial ] equation { equation ";" } - ( "initial" )? "equation" ( equation() ";" )* + ( "initial" )? "equation" ( LOOKAHEAD(2) equation() ";" )* } void algorithm_section() : { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java index bf4f2ad7..ef856249 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -50,7 +50,7 @@ public abstract class IndependentVariable extends Variable { // [= expression] if(variability == Variability.PARAMETER || variability == Variability.CONSTANT) { // parameters and constants are guaranteed to have only one expression - String equation = FormatUtils.formatExpressionForModelica(this, getExpressions().get(0).getExpression(this)); + String equation = FormatUtils.formatExpressionForModelica(this, getExpressions().get(0).getExpression()); sb.append(" = " + equation); } @@ -61,7 +61,7 @@ public abstract class IndependentVariable extends Variable { if(getExpressions() != null) { String addition; for(IExpression e : getExpressions()) { - addition = e.getDeclarationAddition(this); + addition = e.getDeclarationAddition(); if(addition != null) sb.append(addition); } @@ -103,7 +103,7 @@ public abstract class IndependentVariable extends Variable { StringBuilder sb = new StringBuilder(); for(IExpression expression : getExpressions()) { - String initialEquation = expression.getInitialEquation(this); + String initialEquation = expression.getInitialEquation(); if(initialEquation != null) sb.append(initialEquation); } @@ -140,12 +140,12 @@ public abstract class IndependentVariable extends Variable { if(firstExpression == null) return null; else - return firstExpression.getEquation(this); + return firstExpression.getEquation(); } else { // ARRAY variable. Create all equations for the variable StringBuilder sb = new StringBuilder(); for(IExpression expression : expressions) { - sb.append(expression.getEquation(this)); + sb.append(expression.getEquation()); } return sb.toString(); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java index 7b740633..8e259bbf 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Stock.java @@ -66,7 +66,7 @@ public class Stock extends IndependentVariable { } else { // Start parameter is used. Parameter guarantees that there is only one expression. StockExpression e = (StockExpression)getExpressions().get(0); - String initialEquation = e.getExpression(this); + String initialEquation = e.getExpression(); initialEquation = SheetFormatUtils.reformatSheetReferences(this, initialEquation); if(getArrayIndexes() != null && !getArrayIndexes().isEmpty()) @@ -79,7 +79,7 @@ public class Stock extends IndependentVariable { getName() + getRange() + "(" + - (e.getStartValue(this) != null ? each : "") + + (e.getStartValue() != null ? each : "") + " start=" + initialEquation + ", " + diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java index c5d0a340..27f33a69 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java @@ -202,7 +202,7 @@ public enum Variability { org.simantics.sysdyn.representation.expressions.IExpression ie = expressions.get(0); - String expression = ie.getExpression(variable); + String expression = ie.getExpression(); return getVariability(variable, expression, allowVariableReferences, configuration); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java index b5109d9d..13124654 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variable.java @@ -45,6 +45,9 @@ public abstract class Variable implements IElement { @RelatedValue(SysdynResource.URIs.Variable_variability) protected String variability; + @RelatedValue(SysdynResource.URIs.Variable_unit) + protected String unit; + /** * Return the variability of this variable (Used in practice only with Input variables) * @return Variability @@ -99,4 +102,12 @@ public abstract class Variable implements IElement { return this.expressions; } + /** + * + * @return Units of this variable + */ + public String getUnit() { + return this.unit; + } + } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java index 5490f308..2e4a5dad 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ConstantExpression.java @@ -14,7 +14,6 @@ package org.simantics.sysdyn.representation.expressions; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; -import org.simantics.sysdyn.representation.IndependentVariable; /** * Represents a constant expression @@ -29,7 +28,7 @@ public class ConstantExpression extends Expression { private String equation; @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return equation; } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java index 1c63ec0d..6a296c80 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/DelayExpression.java @@ -16,7 +16,6 @@ import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.Variability; -import org.simantics.sysdyn.representation.Variable; import org.simantics.sysdyn.representation.utils.FormatUtils; import org.simantics.sysdyn.representation.utils.IndexUtils; @@ -61,27 +60,27 @@ public class DelayExpression extends Expression { private String equation; @Override - public String getDeclarationAddition(IndependentVariable variable) { + public String getDeclarationAddition() { - String delayTime = FormatUtils.formatExpressionForModelica(variable, this.delayTime); - String initialValue = FormatUtils.formatExpressionForModelica(variable, this.initialValue); - Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, delayTime); + String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime); + String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue); + Variability delayTimeVariability = Variability.getVariability((IndependentVariable)parent, delayTime); Variability initialVariability = Variability.CONTINUOUS; if(initialValue != null && initialValue.length() > 0) { /* * By default, initial value variability is continuous. * If initial value has been set, it can be some other. */ - initialVariability = Variability.getVariability(variable, initialValue); + initialVariability = Variability.getVariability(parent, initialValue); } StringBuilder declaration = new StringBuilder(); - String range = variable.getRange(); + String range = parent.getRange(); // Delay declaration - declaration.append(" " + variable.getName() + "_delayClass " + variable.getName() + "_delayClass_instance"); + declaration.append(" " + parent.getName() + "_delayClass " + parent.getName() + "_delayClass_instance"); // Change enumeration sizes from the delay class. Supports overridden enumerations in modules. if(range.length() > 0 || !initialVariability.equals(Variability.CONTINUOUS) || !delayTimeVariability.equals(Variability.CONTINUOUS)) { @@ -120,7 +119,7 @@ public class DelayExpression extends Expression { declaration.append(";\n"); // Write the delay class - declaration.append(getDelayClass(variable, range, order)); + declaration.append(getDelayClass(range, order)); return declaration.toString(); } @@ -134,10 +133,10 @@ public class DelayExpression extends Expression { * @param n Order of the delay * @return */ - private String getDelayClass(Variable variable, String range, int n) { + private String getDelayClass(String range, int n) { StringBuilder sb = new StringBuilder(); - sb.append("class " + variable.getName() + "_delayClass\n"); + sb.append("class " + parent.getName() + "_delayClass\n"); // Enumeration sizes as parameters. Sizes correspond the enumeration sizes of variable if(range.length() > 0) { @@ -147,8 +146,8 @@ public class DelayExpression extends Expression { } } - String dt = FormatUtils.formatExpressionForModelica(variable,delayTime); - Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, dt); + String dt = FormatUtils.formatExpressionForModelica(parent,delayTime); + Variability delayTimeVariability = Variability.getVariability(parent, dt); if(!delayTimeVariability.equals(Variability.CONTINUOUS)) { // Auxiliary variable sb.append("\t" + delayTimeVariability.getText() + " Real" + range + " DL = delayTime/" + n + ";\n"); @@ -164,9 +163,9 @@ public class DelayExpression extends Expression { // Get initial value variability Variability initialValueVariability = Variability.CONTINUOUS; - String initEquation = FormatUtils.formatExpressionForModelica(variable, this.initialValue); + String initEquation = FormatUtils.formatExpressionForModelica(parent, this.initialValue); if(initialValue != null && initialValue.length() > 0) { - initialValueVariability = Variability.getVariability((IndependentVariable)variable, initEquation); + initialValueVariability = Variability.getVariability(parent, initEquation); } // Declare initial value (continuous or other) @@ -209,47 +208,47 @@ public class DelayExpression extends Expression { sb.append("\tdelay" + i + " = LV" + i + " " + (range.isEmpty() ? "/" : "./") + "DL;\n"); } - sb.append("end " + variable.getName() + "_delayClass;\n"); + sb.append("end " + parent.getName() + "_delayClass;\n"); return sb.toString(); } @Override - public String getEquation(IndependentVariable variable) { + public String getEquation() { StringBuilder sb = new StringBuilder(); - String equation = FormatUtils.formatExpressionForModelica(variable, this.equation); - String delayTime = FormatUtils.formatExpressionForModelica(variable, this.delayTime); - String initialValue = FormatUtils.formatExpressionForModelica(variable, this.initialValue); + String equation = FormatUtils.formatExpressionForModelica(parent, this.equation); + String delayTime = FormatUtils.formatExpressionForModelica(parent, this.delayTime); + String initialValue = FormatUtils.formatExpressionForModelica(parent, this.initialValue); // First "valve" in the delay - sb.append(" " + variable.getName() + "_delayClass_instance.delay0 = " + equation + ";\n"); + sb.append(" " + parent.getName() + "_delayClass_instance.delay0 = " + equation + ";\n"); // Delay time (if continuous) - Variability delayTimeVariability = Variability.getVariability((IndependentVariable)variable, delayTime); + Variability delayTimeVariability = Variability.getVariability(parent, delayTime); if(delayTimeVariability.equals(Variability.CONTINUOUS)) { - sb.append(" " + variable.getName() + "_delayClass_instance.delayTime = " + delayTime + ";\n"); + sb.append(" " + parent.getName() + "_delayClass_instance.delayTime = " + delayTime + ";\n"); } // Initial value if(initialValue == null || initialValue.length() == 0) { // No initial value set, use delay0 (the first "valve") - sb.append(" " + variable.getName() + "_delayClass_instance.initialValue = " + variable.getName() + "_delayClass_instance.delay0;\n"); + sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + parent.getName() + "_delayClass_instance.delay0;\n"); } else { // Continuous initial value - Variability initialVariability = Variability.getVariability(variable, initialValue); + Variability initialVariability = Variability.getVariability(parent, initialValue); if(initialVariability.equals(Variability.CONTINUOUS)) { - sb.append(" " + variable.getName() + "_delayClass_instance.initialValue = " + initialValue + ";\n"); + sb.append(" " + parent.getName() + "_delayClass_instance.initialValue = " + initialValue + ";\n"); } } // The value of the actual variable - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); - sb.append(" " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + variable.getName() + "_delayClass_instance.delay" + order + ";\n"); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + sb.append(" " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + parent.getName() + "_delayClass_instance.delay" + order + ";\n"); return sb.toString(); } @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return "This + is + not + a + parameter + at + any + time"; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java index 1d9d77fa..9f5f28f0 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/Expression.java @@ -11,9 +11,14 @@ *******************************************************************************/ package org.simantics.sysdyn.representation.expressions; +import org.simantics.db.ReadGraph; +import org.simantics.layer0.Layer0; +import org.simantics.objmap.IMapping; +import org.simantics.objmap.annotations.RelatedElement; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.sysdyn.representation.utils.UnitUtils; /** * Abstract class for any expression @@ -25,24 +30,27 @@ public abstract class Expression implements IExpression { @RelatedValue(SysdynResource.URIs.Expression_arrayRange) private String range; + + @RelatedElement(Layer0.URIs.PartOf) + protected IndependentVariable parent; @Override - public String getEquation(IndependentVariable variable) { + public String getEquation() { return null; } @Override - public String getInitialEquation(IndependentVariable variable) { + public String getInitialEquation() { return null; } @Override - public String getDeclarationAddition(IndependentVariable variable) { + public String getDeclarationAddition() { return null; } @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return null; } @@ -54,4 +62,13 @@ public abstract class Expression implements IExpression { return range; } + @Override + public String matchUnits() { + return UnitUtils.matchUnits(null, null, parent, getExpression()); + } + + @Override + public String matchUnits(ReadGraph graph, IMapping mapping) { + return UnitUtils.matchUnits(graph, mapping, parent, getExpression()); + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java index c3f7ae77..48ecdaa4 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/IExpression.java @@ -11,7 +11,9 @@ *******************************************************************************/ package org.simantics.sysdyn.representation.expressions; -import org.simantics.sysdyn.representation.IndependentVariable; +import org.simantics.db.ReadGraph; +import org.simantics.objmap.IMapping; + /** * Interface for all expressions in System Dynamics models @@ -27,21 +29,21 @@ public interface IExpression { * @param variable Declared independent variable * @return additions or null */ - String getDeclarationAddition(IndependentVariable variable); + String getDeclarationAddition(); /** * Initial value for this variable and expression * @param variable IndependentVariable * @return initial value or null */ - String getInitialEquation(IndependentVariable variable); + String getInitialEquation(); /** * Get the actual equation of this expression * @param variable IndependentVariable * @return equation or null */ - String getEquation(IndependentVariable variable); + String getEquation(); /** * Get the range of this expression @@ -54,6 +56,22 @@ public interface IExpression { * @param variable * @return */ - String getExpression(IndependentVariable variable); - + String getExpression(); + + + /** + * Match the units of this expression to units of its variable + * @return null if match, Error message otherwise + */ + String matchUnits(); + + /** + * Match the units of this expression to units of its variable. + * + * Requests units of referred variables for request listening + * @param graph ReadGraph + * @param mapping ObjMap mapping + * @return null if match, ERror message otherwise + */ + String matchUnits(ReadGraph graph, IMapping mapping); } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java index a0501b47..a8d4d667 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/NormalExpression.java @@ -14,7 +14,6 @@ package org.simantics.sysdyn.representation.expressions; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; -import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.utils.FormatUtils; import org.simantics.sysdyn.representation.utils.IndexUtils; @@ -31,15 +30,15 @@ public class NormalExpression extends Expression { private String equation; @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return equation; } @Override - public String getEquation(IndependentVariable variable) { - String equation = FormatUtils.formatExpressionForModelica(variable, this.equation); - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); - return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; + public String getEquation() { + String equation = FormatUtils.formatExpressionForModelica(parent, this.equation); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java index 874de79a..96ba6899 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/ParameterExpression.java @@ -14,7 +14,6 @@ package org.simantics.sysdyn.representation.expressions; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; -import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.utils.IndexUtils; /** @@ -30,12 +29,12 @@ public class ParameterExpression extends Expression { private String equation; @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return equation + " /* Actual value read from init file */"; } @Override - public String getDeclarationAddition(IndependentVariable variable) { + public String getDeclarationAddition() { return ""; } @@ -44,9 +43,9 @@ public class ParameterExpression extends Expression { * Used when the expression is a part of an array variable. Then it is like a normal auxiliary. */ @Override - public String getEquation(IndependentVariable variable) { - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); - return " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; + public String getEquation() { + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); + return " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = " + equation + ";\n"; }; public Double getValue() { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java index 13ee73ea..17e1a78e 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/StockExpression.java @@ -23,7 +23,6 @@ import org.simantics.sysdyn.expressionParser.ParseException; import org.simantics.sysdyn.representation.Book; import org.simantics.sysdyn.representation.Enumeration; import org.simantics.sysdyn.representation.IElement; -import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.Sheet; import org.simantics.sysdyn.representation.Stock; import org.simantics.sysdyn.representation.Valve; @@ -43,29 +42,29 @@ public class StockExpression extends Expression { private String initialEquation; @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return initialEquation; } @Override - public String getEquation(IndependentVariable variable) { + public String getEquation() { // Build range e.g. Stock[2,3] - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); // Stock equation is always der(Stock) StringBuilder b = new StringBuilder(); b.append(" der(") - .append(variable.getName() + range) + .append(parent.getName() + range) .append(") ="); // Stock equation is formed automatically using incoming and outgoing flows (actually the nearest valves in those flows) - ArrayList incoming = ((Stock)variable).getIncomingValves(); - ArrayList outgoing = ((Stock)variable).getOutgoingValves(); + ArrayList incoming = ((Stock)parent).getIncomingValves(); + ArrayList outgoing = ((Stock)parent).getOutgoingValves(); if(incoming.isEmpty() && outgoing.isEmpty()) { // No connections, add 0 for each array index if any. - ArrayList enumerations = variable.getArrayIndexes(); + ArrayList enumerations = parent.getArrayIndexes(); if(enumerations == null || enumerations.isEmpty()) { b.append(" 0.0"); } else { @@ -93,11 +92,11 @@ public class StockExpression extends Expression { * Check whether to use fixed=true and start=... in Modelica code * @return */ - private boolean useStartValue(IndependentVariable variable) { + private boolean useStartValue() { // If no variables are used in the equation, start value is used // First the equation is formatted and parsed - String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation); + String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation); ExpressionParser parser = new ExpressionParser(new StringReader(equation)); try { parser.expr(); @@ -115,7 +114,7 @@ public class StockExpression extends Expression { // We only need the first element to know that it is a Sheet (SheetName.CellOrRange) reference = reference.split("\\.")[0]; found = false; - for(IElement element : variable.getParentConfiguration().getElements()) { + for(IElement element : parent.getParentConfiguration().getElements()) { if(element instanceof Book) { for(Sheet sheet : ((Book)element).getSheets()) { if(reference.equals(sheet.getName())) { @@ -140,16 +139,16 @@ public class StockExpression extends Expression { } @Override - public String getInitialEquation(IndependentVariable variable) { + public String getInitialEquation() { // if start value is used, no initial equation is returned - if(useStartValue(variable)) + if(useStartValue()) return null; // format the initial equation for modelica execution - String equation = FormatUtils.formatExpressionForModelica(variable, initialEquation, false); - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); + String equation = FormatUtils.formatExpressionForModelica(parent, initialEquation, false); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); if(range == null) range = ""; - return " " + variable.getName() + range + " = " + equation + ";\n"; + return " " + parent.getName() + range + " = " + equation + ";\n"; } @@ -159,12 +158,12 @@ public class StockExpression extends Expression { * @param variable * @return Double representing the initial equation or null if initial equation is not a double */ - public Double getStartValue(IndependentVariable variable) { + public Double getStartValue() { Double value = null; - ArrayList expressions = variable.getExpressions(); + ArrayList expressions = parent.getExpressions(); if(expressions.size() == 1) { IExpression e = expressions.get(0); - if(e.getInitialEquation(variable) == null) { + if(e.getInitialEquation() == null) { try { value = Double.parseDouble(initialEquation); } catch(NumberFormatException e1) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java index f40cc43e..c98ee79a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/WithLookupExpression.java @@ -14,7 +14,6 @@ package org.simantics.sysdyn.representation.expressions; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.SysdynResource; -import org.simantics.sysdyn.representation.IndependentVariable; import org.simantics.sysdyn.representation.utils.FormatUtils; import org.simantics.sysdyn.representation.utils.IndexUtils; import org.simantics.sysdyn.representation.utils.SheetFormatUtils; @@ -34,16 +33,16 @@ public class WithLookupExpression extends Expression { private String equation; @Override - public String getEquation(IndependentVariable variable) { - String equation = FormatUtils.formatExpressionForModelica(variable, this.equation); - String range = IndexUtils.rangeToIndexes(variable, this.getArrayRange()); + public String getEquation() { + String equation = FormatUtils.formatExpressionForModelica(parent, this.equation); + String range = IndexUtils.rangeToIndexes(parent, this.getArrayRange()); return - " " + variable.getName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(variable, lookupTable) + ");\n"; + " " + parent.getName() + (range.equals("[:]") ? "" : range) + " = interpolate(" + equation + ", " + SheetFormatUtils.reformatSheetReferences(parent, lookupTable) + ");\n"; } @Override - public String getExpression(IndependentVariable variable) { + public String getExpression() { return "interpolate(" + equation + ", " + lookupTable + ")"; } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java new file mode 100644 index 00000000..85365768 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/utils/UnitUtils.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.utils; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; +import org.simantics.db.exception.ServiceException; +import org.simantics.objmap.IMapping; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.representation.Configuration; +import org.simantics.sysdyn.representation.IElement; +import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.Variable; +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; +import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull; +import org.simantics.sysdyn.unitParser.nodes.UnitResult; + +public class UnitUtils { + + public static String matchUnits(ReadGraph graph, IMapping mapping, Variable variable, String expression) { + if(variable.getUnit() == null) + return "Unit not defined for " + variable.getName(); + try { + + StringReader rightReader = new StringReader(expression); + UnitParser rightParser = new UnitParser(rightReader); + UnitCheckingNode right = (UnitCheckingNode) rightParser.expr(); + rightReader.close(); + Set components = findComponents(right); + HashMap units = findUnits(graph, mapping, variable, components); + + StringReader leftReader = new StringReader(variable.getUnit()); + UnitParser leftParser = new UnitParser(leftReader); + UnitCheckingNode left = (UnitCheckingNode) leftParser.expr(); + leftReader.close(); + + try { + UnitResult rightUnits = right.getUnits(units); + UnitResult leftUnits = left.getUnits(null); + + if(!rightUnits.equals(leftUnits)) + return leftUnits.getCleanFullUnit() + " != " + rightUnits.getCleanFullUnit(); + } catch (UnitCheckingException e) { + return e.getMessage(); + } + +// node.dump(""); + } catch (ParseException e) { + e.printStackTrace(); + } + + return null; + } + + + private static HashMap findUnits(ReadGraph graph, IMapping mapping, Variable variable, Set components) { + HashMap units = new HashMap(); + Configuration configuration = variable.getParentConfiguration(); + for(String component : components) { + Variable var = getElement(configuration, component); + if(var != null) { + + // Support listening, if graph and mapping exists + if(graph != null && mapping != null) { + Resource varResource = mapping.inverseGet(var); + if(varResource != null) { + try { + graph.getPossibleRelatedValue(varResource, SysdynResource.getInstance(graph).Variable_unit); + } catch (ManyObjectsForFunctionalRelationException e) { + e.printStackTrace(); + } catch (ServiceException e) { + e.printStackTrace(); + } + } + } + + String unit = var.getUnit(); + if(unit != null) { + units.put(component, unit); + } + } + } + + + + return units; + } + + private static Variable getElement(Configuration configuration, String name) { + String[] elements = name.split("\\."); + String element = elements[0]; + for(IElement e : configuration.getElements()) { + if(e instanceof Variable) { + Variable var = (Variable)e; + if(var.getName().equals(element)) + return var; + } else if(e instanceof Module && elements.length > 1) { + Module mod = (Module)e; + if(mod.getName().equals(element)) { + return getElement(mod.getType().getConfiguration(), name.substring(name.indexOf(".") + 1)); + } + } + } + return null; + } + + private static Set findComponents(UnitCheckingNode node) { + HashSet components = new HashSet(); + addComponents(node, components); + return components; + + } + + private static void addComponents(UnitCheckingNode node, HashSet components) { + if(node instanceof ComponentReferenceFull) { + components.add(node.printNode()); + } else { + for(int i = 0; i < node.jjtGetNumChildren(); i++) { + addComponents((UnitCheckingNode)node.jjtGetChild(i), components); + } + } + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java new file mode 100644 index 00000000..481004c9 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingException.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +public class UnitCheckingException extends Exception { + public UnitCheckingException(String string) { + super(string); + } + + private static final long serialVersionUID = -5828012051088095625L; + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java new file mode 100644 index 00000000..e80e60f6 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNode.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +import java.util.ArrayList; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.nodes.UnitResult; + + +public class UnitCheckingNode extends SimpleNode { + + public UnitCheckingNode(int id) { + super(id); + } + + public UnitResult getUnits(HashMap units) throws UnitCheckingException{ + UnitResult result = new UnitResult(); + + if(jjtGetNumChildren() == 0){ + String node = printNode(); + result.append(node); + } else { + for(UnitCheckingNode node : getChildren()) { + result.appendResult(node.getUnits(units)); + } + } + return result; + } + + protected ArrayList getChildren() { + ArrayList children = new ArrayList(); + for(int i = 0; i < jjtGetNumChildren(); i++) { + children.add((UnitCheckingNode)jjtGetChild(i)); + } + return children; + } + + + public String printNode() { + StringBuilder sb = new StringBuilder(); + Token token = jjtGetFirstToken(); + sb.append(token.image); + + while(token != null && !token.equals(jjtGetLastToken())) { + token = token.next; + sb.append(token.image); + } + + return sb.toString(); + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java new file mode 100644 index 00000000..434b982b --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitCheckingNodeFactory.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.nodes.AddOp; +import org.simantics.sysdyn.unitParser.nodes.Arithmetic; +import org.simantics.sysdyn.unitParser.nodes.ComponentIdentity; +import org.simantics.sysdyn.unitParser.nodes.ComponentReference; +import org.simantics.sysdyn.unitParser.nodes.ComponentReferenceFull; +import org.simantics.sysdyn.unitParser.nodes.Condition; +import org.simantics.sysdyn.unitParser.nodes.Divide; +import org.simantics.sysdyn.unitParser.nodes.ForIndex; +import org.simantics.sysdyn.unitParser.nodes.IfThenElse; +import org.simantics.sysdyn.unitParser.nodes.Multiplication; +import org.simantics.sysdyn.unitParser.nodes.RelOp; +import org.simantics.sysdyn.unitParser.nodes.Relation; +import org.simantics.sysdyn.unitParser.nodes.Term; +import org.simantics.sysdyn.unitParser.nodes.Value; + +public class UnitCheckingNodeFactory { + + private static HashMap> constructors = new HashMap>(); + + static { + constructors.put("relation", Relation.class); + constructors.put("term", Term.class); + constructors.put("arithmetic_expression", Arithmetic.class); + constructors.put("ifthenelse", IfThenElse.class); + + constructors.put("component_reference_full", ComponentReferenceFull.class); + constructors.put("value", Value.class); + + + constructors.put("divide", Divide.class); + constructors.put("multiplication", Multiplication.class); + constructors.put("add_op", AddOp.class); + constructors.put("rel_op", RelOp.class); + + + + constructors.put("component_reference", ComponentReference.class); + constructors.put("component_identity", ComponentIdentity.class); + constructors.put("condition", Condition.class); + constructors.put("for_index", ForIndex.class); + + } + + private static Class getConstructor(int id) { + String name = UnitParserTreeConstants.jjtNodeName[id]; + Class constructor = constructors.get(name); + if(constructor == null) + return UnitCheckingNode.class; + else + return constructor; + } + + public static Node jjtCreate(int id) { + try { + return (Node) getConstructor(id).getConstructors()[0].newInstance(id); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt new file mode 100644 index 00000000..e7f87938 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/UnitParser.jjt @@ -0,0 +1,275 @@ +options { + JDK_VERSION = "1.6"; + STATIC = false; + TRACK_TOKENS=true; + NODE_CLASS="UnitCheckingNode"; + NODE_FACTORY="UnitCheckingNodeFactory"; +} + +PARSER_BEGIN(UnitParser) +package org.simantics.sysdyn.unitParser; + +public class UnitParser { + + + +} +PARSER_END(UnitParser) + +/*** Lexer *********************************************************/ + +SKIP: +{ +| +| +} + +TOKEN: +{ +"algorithm" | "discrete" | "false" | "model" | "redeclare" +| "and" | "each" | "final" | "not" | "replaceable" +| "annotation" | "else" | "flow" | "operator" | "return" +|"assert" | "elseif" | "for" | "or" | "stream" +| "block" | "elsewhen" | "function" | "outer" | "then" +| "break" | "encapsulated" | "if" | "output" | "true" +| "class" | "end" | "import" | "package" | "type" +| "connect" | "enumeration" | "in" | "parameter" | "when" +| "connector" | "equation" | /*"initial" |*/ "partial" | "while" +| "constant" | "expandable" | "inner" | "protected" | "within" +| "constrainedby" | "extends" | "input" | "public" +| /*"der" |*/ "external" | "loop" | "record" +| "(" | ")" | "{" | "}" | "[" | "]" | "." | ":" | ";" | "," +| "<" | "<=" | ">" | ">=" | "==" | "<>" +| "+" | "-" | ".+" | ".-" +| "*" | "/" | ".*" | "./" +| "^" | ".^" +| "=" | ":=" +| +| + { matchedToken.image = matchedToken.image.substring(1,matchedToken.image.length()-1); } +| +| "." ()? (["e","E"] )? + | "." (["e","E"] )? + | ["e","E"] + ) > +} + +/*** Parser ********************************************************/ + +// https://javacc.dev.java.net/doc/javaccgrm.html +// add_op -> add_op() +// [ add_op ] -> ( add_op() )? +// { add_op term } -> ( add_op() term() )* + +SimpleNode expr() : { +} { + (simple_expression())? + { + return jjtThis; + } + | + ifthenelse() + { + return jjtThis; + } +} + +void expression() : { +} { + simple_expression() + | ifthenelse() +} + +void ifthenelse() : { } { + "if" condition() "then" expression() ( "elseif" condition() "then" expression() )* "else" expression() +} + +void condition() : { +} { + expression() +} + +void simple_expression() : { +} { + logical_expression() ( ":" logical_expression() ( ":" logical_expression() )? )? +} + +void logical_expression() : { +} { + logical_term() ( "or" logical_term() )* +} + +void logical_term() : { +} { + logical_factor() ( "and" logical_factor() )* +} + +void logical_factor() : { +} { + ( "not" )? relation() +} + +void relation() : { +} { + arithmetic_expression() ( rel_op() arithmetic_expression() )? +} + +void rel_op() : { +} { + "<" | "<=" | ">" | ">=" | "==" | "<>" +} + +void arithmetic_expression() : { +} { + (add_op())? term() (add_op() term())* +} + +void add_op() : { +} { + "+" | "-" | ".+" | ".-" +} + +void term() : { +} { + factor() ( (multiplication() | divide()) factor() )* +} + +void factor() : { +} { + primary() ( "^" primary() | ".^" primary() )? +} + +void multiplication() : { +} { + "*" | ".*" +} + +void divide() : { +} { + "/" | "./" +} + +void primary() : { +} { + value() + | LOOKAHEAD( name() parenthesis_open() ) function_call() + | component_reference_full() + /*| "(" output_expression_list() ")"*/ // Not needed, replaced with following: + | parenthesis_expression() + | "[" expression_list() ( ";" expression_list() )* "]" + | "{" function_arguments() "}" + | "end" +} + +void component_reference_full() : { +} { + component_reference() +} + +void function_call() : { +} { + name() function_call_args() +} + +void parenthesis_expression() : { } { parenthesis_open() expression() parenthesis_close() +} + +void value() : { } { + + | + | + | "false" + | "true" +} + +void parenthesis_open() : { +} { + "(" +} + +void parenthesis_close() : { +} { + ")" +} + +void name() : { +} { + ( "." name() )? +} + +void component_reference() : { +} { + //IDENT [ array_subscripts ] [ "." component_reference ] + component_identity() ( array_subscripts() )? ( "." component_reference() )? +} + +void component_identity() : { +} { +} + +void function_call_args() : { +} { + parenthesis_open() ( function_arguments() )? parenthesis_close() +} + +void function_arguments() : { +} { + //expression [ "," function_arguments | for for_indices ] + //| named_arguments + LOOKAHEAD(2) named_argument() ( "," function_arguments() )? + | expression() ( "," function_arguments() | "for" for_indices() )? + +} + +void for_indices() : { +} { + //for_index {"," for_index} + for_index() ("," for_index())* +} + +void for_index() : { +} { + //IDENT [ in expression ] + ( "in" expression() )? +} + +/* Removed by Teemu. Refactored in function_arguments) +void named_arguments() : { +} { + named_argument() ( "," named_arguments() )? +} +*/ + +void named_argument() : { +} { + "=" expression() +} + +void output_expression_list() : { +} { + ( expression() )? ( "," ( expression() )? )* +} + + +void expression_list() : { +} { + expression() ( "," expression() )* +} + +void array_subscripts() : { +} { + "[" subscript() ( "," subscript() )* "]" +} + +void subscript() : { +} { ":" + | LOOKAHEAD( name() parenthesis_open() ) name() function_call_args() + | rangeIndex() ( ":" rangeIndex())? +} + +void rangeIndex() : { +} { + | +} + diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java new file mode 100644 index 00000000..9c3374c8 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/AddOp.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class AddOp extends UnitCheckingNode { + + public AddOp(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = super.getUnits(units); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java new file mode 100644 index 00000000..a24ef52d --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Arithmetic.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Arithmetic extends UnitCheckingNode { + + public Arithmetic(int id) { + super(id); + } + + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = new UnitResult(); + + UnitCheckingNode base = null; + UnitCheckingNode operator = null; + UnitCheckingNode candidateNode = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult candidateUnits = candidateNode.getUnits(units); + if(candidateUnits.getUnitType() == UnitType.OPERATOR || candidateUnits.getUnitType() == UnitType.ANY) { + result.setUnitType(candidateUnits.getUnitType()); + continue; + } else if(base == null) { + base = ((UnitCheckingNode)jjtGetChild(i)); + result.appendResult(base.getUnits(units)); + continue; + } else { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + if(!result.equals(candidateUnits)) { + throw new UnitCheckingException("Not equals exception: " + + base.printNode() + " [" + result.getCleanFullUnit() + "] " + operator.printNode() + " " + + candidateNode.printNode() + " [" + candidateUnits.getCleanFullUnit() + "]" + ); + } + } + } + + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java new file mode 100644 index 00000000..c32b47f6 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentIdentity.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ComponentIdentity extends UnitCheckingNode { + + public ComponentIdentity(int id) { + super(id); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java new file mode 100644 index 00000000..b9541bbd --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReference.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ComponentReference extends UnitCheckingNode { + + public ComponentReference(int id) { + super(id); + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < jjtGetNumChildren(); i++) { + UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i); + if(node instanceof ComponentIdentity || node instanceof ComponentReference) { + if(sb.length() > 0) + sb.append("."); + sb.append(node.printNode()); + } + } + return sb.toString(); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java new file mode 100644 index 00000000..d771dc3d --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ComponentReferenceFull.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.io.StringReader; +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.ParseException; +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.UnitParser; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ComponentReferenceFull extends UnitCheckingNode { + + public ComponentReferenceFull(int id) { + super(id); + } + + protected UnitResult parseUnits(String units) { + StringReader sr = new StringReader(units); + UnitParser parser = new UnitParser(sr); + try { + UnitCheckingNode node = (UnitCheckingNode) parser.expr(); + return node.getUnits(null); + } catch (ParseException e) { + e.printStackTrace(); + } catch (UnitCheckingException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + String node = printNode(); + node = printNode(); + if(units != null) { + if(!units.containsKey(node)) + throw new UnitCheckingException("No units defined for " + node); + else { + return parseUnits(units.get(node)); + } + } else { + UnitResult result = new UnitResult(); + result.addDivident(node); + result.append(node); + return result; + } + } + + @Override + public String printNode() { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < jjtGetNumChildren(); i++) { + UnitCheckingNode node = (UnitCheckingNode) jjtGetChild(i); + sb.append(node.printNode()); + } + return sb.toString(); + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java new file mode 100644 index 00000000..c382cda3 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Condition.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Condition extends UnitCheckingNode { + + public Condition(int id) { + super(id); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java new file mode 100644 index 00000000..4c2ec48e --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Divide.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Divide extends UnitCheckingNode { + + public Divide(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = super.getUnits(units); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java new file mode 100644 index 00000000..0d934f12 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/ForIndex.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class ForIndex extends UnitCheckingNode { + + public ForIndex(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + return new UnitResult(); + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java new file mode 100644 index 00000000..f5942e4e --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/IfThenElse.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class IfThenElse extends UnitCheckingNode { + + public IfThenElse(int id) { + super(id); + } + + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult base = null; + UnitCheckingNode baseNode = null; + UnitCheckingNode candidateNode = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult candidateUnits = candidateNode.getUnits(units); + + if(!(candidateNode instanceof Condition)) { + + if(base == null) { + base = candidateUnits; + baseNode = candidateNode; + } else { + if(!base.equals(candidateUnits)) { + base.equals(candidateUnits); + throw new UnitCheckingException("Conditional results do not have same units: \n" + + printNode() + "\n" + + baseNode.printNode() + " [" + base.getFullUnit() + "] <-> " + + candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]" + ); + } + } + } + + + } + + return base; + } + + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java new file mode 100644 index 00000000..53cdc783 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Multiplication.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Multiplication extends UnitCheckingNode { + + public Multiplication(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = super.getUnits(units); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java new file mode 100644 index 00000000..57098ba1 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/RelOp.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class RelOp extends UnitCheckingNode { + + public RelOp(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = super.getUnits(units); + result.setUnitType(UnitType.OPERATOR); + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java new file mode 100644 index 00000000..6d8711c1 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Relation.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Relation extends UnitCheckingNode { + + public Relation(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = new UnitResult(); + + UnitCheckingNode base = null; + UnitCheckingNode operator = null; + UnitCheckingNode candidateNode = null; + + base = ((UnitCheckingNode)jjtGetChild(0)); + if(!(base instanceof Arithmetic) && jjtGetNumChildren() > 1) + base = ((UnitCheckingNode)jjtGetChild(1)); + + if(base instanceof Arithmetic) { + result.appendResult(base.getUnits(units)); + + for(int i = 2; i < jjtGetNumChildren(); i = i + 2) { + candidateNode = ((UnitCheckingNode)jjtGetChild(i)); + + if(!(candidateNode instanceof Value)) { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + UnitResult candidateUnits = candidateNode.getUnits(units); + if(!result.equals(candidateUnits)) { + result.equals(candidateUnits); + throw new UnitCheckingException("Not equals exception: " + + base.printNode() + " [" + result.getFullUnit() + "] " + operator.printNode() + " " + + candidateNode.printNode() + " [" + candidateUnits.getFullUnit() + "]" + ); + } + } + + } + } + + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java new file mode 100644 index 00000000..77408c00 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Term.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Term extends UnitCheckingNode { + + public Term(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = new UnitResult(); + + UnitCheckingNode current = null; + UnitCheckingNode operator = null; + UnitCheckingNode base = null; + + for(int i = 0; i < jjtGetNumChildren(); i++) { + current = ((UnitCheckingNode)jjtGetChild(i)); + UnitResult currentUnits = current.getUnits(units); + + if(currentUnits.getUnitType() == UnitType.OPERATOR) { + continue; + } else if(base == null) { + base = current; + result.appendResult(currentUnits); + continue; + } else { + operator = ((UnitCheckingNode)jjtGetChild(i-1)); + + if(operator instanceof Multiplication) { + if(currentUnits.getUnitType() != UnitType.ANY) { + result.append(operator.printNode()); + result.appendResult(currentUnits); + } + } else if(operator instanceof Divide){ + result.append(operator.printNode()); + result.addAllDividers(currentUnits.getDividers()); + result.addAllDividers(currentUnits.getDividents()); + result.setUnitType(currentUnits.getUnitType()); + + if(currentUnits.getUnitType() == UnitType.ANY) + result.append("1"); + else + result.append(currentUnits.getFullUnit()); + } + } + } + + return result; + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java new file mode 100644 index 00000000..27851346 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/UnitResult.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; + +/** + * Result of getUnits() request for Unit Parser nodes. + * + * Result is built of dividers and dividents. ( divident / divider ) + * + * UnitType may provide information for handling this unit result + * + * fullUnit is the print of this unit in the order it is created. + * + * getCleanFullUnit reduces all unnecessary units and provides the most + * clean representation of the unit. ( e.g. m * s / m -> s ) + * + * @author Teemu Lempinen + * + */ +public class UnitResult { + + public enum UnitType {NORMAL, ANY, DMNL, OPERATOR}; + + private ArrayList dividers = new ArrayList(); + private ArrayList dividents = new ArrayList(); + private StringBuilder fullUnit = new StringBuilder(); + private UnitType unitType = UnitType.NORMAL; + + public void appendResult(UnitResult result) { + addAllDividents(result.getDividents()); + addAllDividers(result.getDividers()); + append(result.getFullUnit()); + setUnitType(result.getUnitType()); + } + + public void addDivider(String divider) { + this.dividers.add(divider); + Collections.sort(this.dividers); + } + + public void addAllDividers(ArrayList dividers) { + this.dividers.addAll(dividers); + Collections.sort(this.dividers); + } + + public void addDivident(String divident) { + this.dividents.add(divident); + Collections.sort(this.dividents); + } + + public void addAllDividents(ArrayList dividents) { + this.dividents.addAll(dividents); + Collections.sort(this.dividents); + } + + public void append(String text) { + this.fullUnit.append(text); + } + + public ArrayList getDividers() { + return this.dividers; + } + + public ArrayList getDividents() { + return this.dividents; + } + + public String getFullUnit() { + return fullUnit.toString(); + } + + + /** + * Get clean representation of this unit. All redundant + * units are cleanend out and the unit is represented + * with max one '/' character. + * @return + */ + public String getCleanFullUnit() { + if(dividers.size() == 0 && dividents.size() == 0) + return ""; + + if(dividers.size() > 0 && dividents.size() == 0) + dividents.add("1"); + + ArrayList copyDividers1 = new ArrayList(dividers); + ArrayList copyDividents1 = new ArrayList(dividents); + reduceUnitLists(dividents, copyDividents1, copyDividers1); + + StringBuilder sb = new StringBuilder(); + Iterator iterator = copyDividents1.iterator(); + while(iterator.hasNext()) { + String s = iterator.next(); + sb.append(s); + if(iterator.hasNext()) + sb.append("*"); + } + + if(copyDividers1.size() > 0) { + sb.append("/"); + if(copyDividers1.size() > 1) + sb.append("("); + + iterator = copyDividers1.iterator(); + while(iterator.hasNext()) { + String s = iterator.next(); + sb.append(s); + if(iterator.hasNext()) + sb.append("*"); + } + + if(copyDividers1.size() > 1) + sb.append(")"); + } + + return sb.toString(); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof UnitResult)) + return false; + + UnitResult other = (UnitResult)obj; + + if(getUnitType() == UnitType.ANY || other.getUnitType() == UnitType.ANY) + return true; + + ArrayList copyDividers1 = new ArrayList(dividers); + ArrayList copyDividents1 = new ArrayList(dividents); + reduceUnitLists(dividents, copyDividents1, copyDividers1); + + ArrayList copyDividers2 = new ArrayList(other.dividers); + ArrayList copyDividents2 = new ArrayList(other.dividents); + reduceUnitLists(other.dividents, copyDividents2, copyDividers2); + + if(copyDividents1.size() != copyDividents2.size()) + return false; + if(copyDividers1.size() != copyDividers2.size()) + return false; + + for(int i = 0; i < copyDividents1.size(); i++) { + String a = copyDividents1.get(i); + String b = copyDividents2.get(i); + if(!a.equals(b)) { + return false; + } + } + + for(int i = 0; i < copyDividers1.size(); i++) { + String a = copyDividers1.get(i); + String b = copyDividers2.get(i); + if(!a.equals(b)) { + return false; + } + } + + return true; + } + + public void reduceUnitLists(ArrayList originalDividents, ArrayList copyDividents, ArrayList copyDividers) { + for(String s : originalDividents) { + if(copyDividers.contains(s)) { + copyDividers.remove(s); + copyDividents.remove(s); + } + } + + if(copyDividents.isEmpty()) + copyDividents.add("1"); + } + + public UnitType getUnitType() { + return unitType; + } + + public void setUnitType(UnitType unitType) { + this.unitType = unitType; + } +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java new file mode 100644 index 00000000..3da4c149 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/unitParser/nodes/Value.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2013 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.unitParser.nodes; + +import java.util.HashMap; + +import org.simantics.sysdyn.unitParser.UnitCheckingException; +import org.simantics.sysdyn.unitParser.UnitCheckingNode; +import org.simantics.sysdyn.unitParser.nodes.UnitResult.UnitType; + +/** + * See UnitCheckingNodeFactory for mapping + * @author Teemu Lempinen + * + */ +public class Value extends UnitCheckingNode { + + public Value(int id) { + super(id); + } + + @Override + public UnitResult getUnits(HashMap units) throws UnitCheckingException { + UnitResult result = super.getUnits(units); + result.setUnitType(UnitType.ANY); + return result; + } +}