X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.modeling%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2FInvertBasicExpressionVisitor.java;h=6293cbac9fd7d9c9fe3c6989e33ac368b5784fe5;hp=11351f06b6a2cf64d05f5e5b2228e5781bd2f617;hb=1819be12c9a971df1dea5daa8190162ac1e20bb6;hpb=60652a89994f8050111b5c243323f6ed703c929a diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java index 11351f06b..6293cbac9 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java @@ -1,14 +1,6 @@ package org.simantics.modeling; -import java.util.Stack; - import org.simantics.basicexpression.Expressions; -import org.simantics.basicexpression.analysis.DepthFirstAdapter; -import org.simantics.basicexpression.node.AConstantValue; -import org.simantics.basicexpression.node.ADivMultiplicative; -import org.simantics.basicexpression.node.AMultMultiplicative; -import org.simantics.basicexpression.node.APlusExpression; -import org.simantics.basicexpression.node.AVariablePrimary; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; @@ -19,125 +11,30 @@ import org.simantics.structural.stubs.StructuralResource2; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.Triple; -public class InvertBasicExpressionVisitor extends DepthFirstAdapter { - - Stack stack = new Stack(); - - public Object getResult() { - if(stack.size() != 1) return null; - return stack.pop(); - } - - public void outAConstantValue(AConstantValue node) { - stack.push(Double.valueOf(node.toString())); - } - - @Override - public void outAVariablePrimary(AVariablePrimary node) { - String value = node.toString().trim(); - stack.push(Triple.make(1.0, 0.0, value)); - } - - @SuppressWarnings("unchecked") - public void outAPlusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first, p.second + (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second + (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 + (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMinusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(-p.first, (Double)o1 - p.second, p.third )); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second - (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 - (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMultMultiplicative(AMultMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 * (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outADivMultiplicative(ADivMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - stack.push(Double.NaN); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first / (Double)o2, p.second / (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 / (Double)o2); - } else { - stack.push(Double.NaN); - } - - } +public class InvertBasicExpressionVisitor extends InvertBasicExpressionVisitorBase { private static final String MAGIC = "_111_"; - + private static String replaced(String expression) { return expression.replaceAll("\\.([A-Za-z])", MAGIC + "$1"); } - + public static void invert(WriteGraph graph, Variable base, String expression, Object value) throws DatabaseException { InvertBasicExpressionVisitor visitor = new InvertBasicExpressionVisitor(); Expressions.evaluate(replaced(expression), visitor); - Object pair = visitor.getResult(); - if(pair == null) return; - if(pair instanceof Triple) { + Object result = visitor.getResult(); + if(result == null) return; + if(result instanceof Triple) { @SuppressWarnings("unchecked") - Triple data = (Triple)pair; + Triple data = (Triple)result; String key = data.third.replace(MAGIC, "."); String path = getVariablePath(graph, base, key); Variable targetVariable = base.browse(graph, path); if(value instanceof Number) { if(Math.abs(data.first) > 1e-9) { - Double inverted = (((Number)value).doubleValue() - data.second) / data.first; - targetVariable.setValue(graph, inverted); + double inverted = (double) (((Number)value).doubleValue() - data.second) / data.first; + Object invertedValue = numericValueInType(inverted, value.getClass()); + targetVariable.setValue(graph, invertedValue); } } else if (value instanceof Boolean) { // TODO: support 'not' @@ -146,7 +43,20 @@ public class InvertBasicExpressionVisitor extends DepthFirstAdapter { } } - + + private static Object numericValueInType(double value, Class type) { + if (type == Integer.class) { + return (int) value; + } else if (type == Long.class) { + return (long) value; + } else if (type == Byte.class) { + return (byte) value; + } else if (type == Float.class) { + return (float) value; + } + return value; + } + private static String getVariablePath(ReadGraph graph, Variable base, String key) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource type = base.getPossibleType(graph); @@ -194,26 +104,36 @@ public class InvertBasicExpressionVisitor extends DepthFirstAdapter { } - public static Variable possibleInvertibleExpressionReferencedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + @SuppressWarnings("unchecked") + private static Triple possibleInvertibleExpression(ReadGraph graph, Variable base, String expression) throws DatabaseException { if (base == null || expression == null || expression.isEmpty()) return null; InvertBasicExpressionVisitor visitor = new InvertBasicExpressionVisitor(); //System.out.println("invert : " + expression + " -> " + replaced(expression) + " for " + base.getURI(graph)); Expressions.evaluate(replaced(expression), visitor); - Object pair = visitor.getResult(); - if(pair == null) - return null; - if(pair instanceof Triple) { - @SuppressWarnings("unchecked") - Triple data = (Triple)pair; - String key = data.third.replace(MAGIC,"."); - String path = getVariablePath(graph, base, key); - if (path == null) - return null; - Variable targetVariable = base.browsePossible(graph, path); - return targetVariable; - } + Object result = visitor.getResult(); + if (result instanceof Triple) + return (Triple) result; return null; } + public static Variable possibleInvertibleExpressionReferencedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + Triple data = possibleInvertibleExpression(graph, base, expression); + if (data == null) + return null; + String path = getVariablePath(graph, base, data.third.replace(MAGIC, ".")); + return path != null ? base.browsePossible(graph, path) : null; + } + + public static Triple possibleInvertibleExpressionReferencedTransformedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + Triple data = possibleInvertibleExpression(graph, base, expression); + if (data == null) + return null; + String path = getVariablePath(graph, base, data.third.replace(MAGIC, ".")); + if (path == null) + return null; + Variable targetVariable = base.browsePossible(graph, path); + return targetVariable != null ? Triple.make(data.first, data.second, targetVariable) : null; + } + }