/******************************************************************************* * Copyright (c) 2007, 2010 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.scenegraph.profile.impl; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.Stack; import org.simantics.basicexpression.analysis.DepthFirstAdapter; import org.simantics.basicexpression.node.AAddressValue; import org.simantics.basicexpression.node.AConstantValue; import org.simantics.basicexpression.node.ADivMultiplicative; import org.simantics.basicexpression.node.AFunctionPrimary; import org.simantics.basicexpression.node.AMultMultiplicative; import org.simantics.basicexpression.node.APlusExpression; import org.simantics.basicexpression.node.ARangeValue; import org.simantics.basicexpression.node.ASequenceArgList; import org.simantics.basicexpression.node.ASingleArgList; import org.simantics.basicexpression.node.AStringValue; import org.simantics.basicexpression.node.AVariablePrimary; import org.simantics.basicexpression.node.PArgList; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.Valuations; import org.simantics.layer0.Layer0; import org.simantics.scl.reflection.OntologyVersions; public class MappedPropertyStyleEvaluator extends DepthFirstAdapter { public static class ApplicationException extends Exception { private static final long serialVersionUID = 1L; public ApplicationException(String message) { super(message); } } public interface Function { Object evaluate(Collection args) throws ApplicationException; } final ReadGraph graph; final Layer0 b; final Resource component; public MappedPropertyStyleEvaluator(ReadGraph graph, Resource element) throws DatabaseException { this.graph = graph; b = Layer0.getInstance(graph); String uri = OntologyVersions.getInstance().currentVersion("http://www.simantics.org/Modeling-0.0/ElementToComponent"); Resource toComponent = graph.getResource(uri); component = graph.getPossibleObject(element, toComponent); } Stack stack = new Stack(); HashMap builtins = new HashMap(); public Object getResult() { if (stack.isEmpty()) return null; return stack.pop(); } @Override public void outAConstantValue(AConstantValue node) { // System.out.println("eval constant " + node); stack.push(Double.valueOf(node.toString())); } @Override public void outAStringValue(AStringValue node) { // System.out.println("eval string " + node.toString()); String value = node.toString(); stack.push(value.substring(1, value.length()-2).trim()); } @Override public void outAVariablePrimary(AVariablePrimary node) { try { Valuations vs = graph.adapt(component, Valuations.class); if(vs == null) { stack.push("No Variables for mapped component."); return; } Resource valueResource = vs.getValue(graph, null, "BaseRealization", node.toString().trim()); if(valueResource == null) { stack.push("Invalid value identifier based on '" + node.toString().trim() + "'"); return; } Object value = graph.getValue(valueResource); stack.push(value); } catch (DatabaseException e) { stack.push(e.toString()); } } @Override public void outAAddressValue(AAddressValue node) { stack.push('&' + node.getRange().toString()); } @Override public void outARangeValue(ARangeValue node) { } private double extractValue(Object o) { if(o instanceof Number) { return ((Number)o).doubleValue(); } else if (o instanceof String) { return Double.valueOf((String)o); } else { return Double.NaN; } } @Override public void outAPlusExpression(APlusExpression node) { Object o2 = stack.pop(); Object o1 = stack.pop(); // System.out.println("plus " + o1 + " " + o2); if(o1 instanceof String) { stack.push(o1.toString() + o2.toString()); } else { double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d1+d2); } } @Override public void outAMultMultiplicative(AMultMultiplicative node) { Object o1 = stack.pop(); Object o2 = stack.pop(); double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d1*d2); // System.out.println("mult " + d1 + " " + d2); } @Override public void outADivMultiplicative(ADivMultiplicative node) { Object o2 = stack.pop(); Object o1 = stack.pop(); System.out.println("div " + o1 + " " + o2); double d1 = extractValue(o1); double d2 = extractValue(o2); stack.push(d1/d2); // System.out.println("div " + d1 + " " + d2); } int countArguments(PArgList args) { if(args == null) return 0; if(args instanceof ASingleArgList) return 1; ASequenceArgList seq = (ASequenceArgList)args; return 1 + countArguments(seq.getArgList()); } @Override public void outAFunctionPrimary(AFunctionPrimary node) { String functionName = node.getFunc().getText().replace("(", ""); //System.out.println(hashCode() + " eval " + functionName); Function function = builtins.get(functionName); if(function != null) { // TODO: fixme LinkedList args = new LinkedList(); int argc = countArguments(node.getArgList()); //System.out.println(hashCode() + "Function takes " + args + " arguments stack has " + Arrays.toString(stack.toArray())); for(int i=0;i