1 package org.simantics.sysdyn.ui.properties.widgets.expressions;
\r
3 import java.io.StringReader;
\r
4 import java.util.ArrayList;
\r
5 import java.util.HashMap;
\r
6 import java.util.HashSet;
\r
7 import java.util.List;
\r
8 import java.util.Set;
\r
10 import org.eclipse.jface.text.Position;
\r
11 import org.eclipse.swt.custom.StyledText;
\r
12 import org.eclipse.swt.graphics.Color;
\r
13 import org.eclipse.swt.widgets.TableItem;
\r
14 import org.simantics.db.Resource;
\r
15 import org.simantics.db.exception.DatabaseException;
\r
16 import org.simantics.sysdyn.expressionParser.ExpressionParser;
\r
17 import org.simantics.sysdyn.expressionParser.ParseException;
\r
18 import org.simantics.sysdyn.expressionParser.Token;
\r
19 import org.simantics.sysdyn.expressionParser.TokenMgrError;
\r
20 import org.simantics.sysdyn.manager.SysdynModel;
\r
21 import org.simantics.sysdyn.manager.SysdynModelManager;
\r
22 import org.simantics.sysdyn.representation.Configuration;
\r
23 import org.simantics.sysdyn.representation.IElement;
\r
24 import org.simantics.sysdyn.representation.Variable;
\r
25 import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;
\r
26 import org.simantics.ui.SimanticsUI;
\r
28 public class ExpressionUtils {
\r
31 * Determines if the given expression is a parameter expression. Parameters are numbers.
\r
32 * If the expression contains anything other than numbers, it is not a parameter.
\r
34 * @param expression The expression to be checked
\r
35 * @return is the expression a parameter
\r
37 static public boolean isParameter(String expression) {
\r
39 Double.parseDouble(expression);
\r
41 } catch (NumberFormatException e) {
\r
46 static public void validateExpressionFields(IExpression expression, TableItem[] connectedVariables, Resource configuration) {
\r
47 ExpressionParser parser = new ExpressionParser(new StringReader(""));
\r
48 Set<String> variables = new HashSet<String>();
\r
49 HashMap<ExpressionField, HashMap<String, List<Token>>> references = new HashMap<ExpressionField, HashMap<String, List<Token>>>();
\r
52 // Build references and variable array
\r
53 for(ExpressionField ef : expression.getExpressionFields()) {
\r
54 ef.resetAnnotations();
\r
55 String textString = ef.getExpression();
\r
56 parser.ReInit(new StringReader(textString));
\r
59 HashMap<String, List<Token>> cr = parser.getReferences();
\r
60 references.put(ef, cr);
\r
61 for(String t : cr.keySet())
\r
63 } catch (ParseException e1) {
\r
64 ef.setSyntaxError(e1.currentToken);
\r
65 } catch (TokenMgrError err) {
\r
66 ef.setSyntaxError(0, textString.length(), "MissingLink", "Expression contains unsupported characters");
\r
70 // Remove variables from variable array that don't exist in the model. Create annotations
\r
71 if(!variables.isEmpty()) {
\r
72 ArrayList<String> modelVariables = new ArrayList<String>();
\r
73 Set<String> noSuchVariables = new HashSet<String>();
\r
74 SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());
\r
75 SysdynModel model = sdm.getModel(configuration);
\r
78 } catch (DatabaseException e1) {
\r
79 e1.printStackTrace();
\r
81 Configuration conf = model.getConfiguration();
\r
82 ArrayList<IElement> elements = conf.getElements();
\r
83 for(IElement e : elements) {
\r
84 if(e instanceof Variable) {
\r
85 Variable v = (Variable) e;
\r
86 modelVariables.add(v.getName());
\r
91 for(String v : variables) {
\r
92 if(!modelVariables.contains(v)) {
\r
93 noSuchVariables.add(v);
\r
97 if(!noSuchVariables.isEmpty()) {
\r
98 // remove no such variables from variable list
\r
99 for(String s : noSuchVariables)
\r
100 variables.remove(s);
\r
101 // create annotations
\r
102 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, noSuchVariables);
\r
103 for(ExpressionField ef : positions.keySet()) {
\r
104 ef.setNoSuchVariableAnnotations(positions.get(ef));
\r
109 // Check that the variables that exist have connections and the connected variables have references in the expressions
\r
110 if(!(expression instanceof StockExpression)) {
\r
111 for(TableItem ti : connectedVariables) {
\r
112 if(!variables.contains(ti.getText())) {
\r
113 ti.setForeground(new Color(ti.getDisplay(), 255, 0, 0));
\r
115 ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));
\r
116 variables.remove(ti.getText());
\r
120 if(!variables.isEmpty()) {
\r
121 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, variables);
\r
122 for(ExpressionField ef : positions.keySet()) {
\r
123 ef.setMissingLinkAnnotations(positions.get(ef));
\r
131 @SuppressWarnings("unchecked")
\r
132 static private HashMap<ExpressionField ,ArrayList<Position>> getPositionsForVariables(HashMap<ExpressionField, HashMap<String, List<Token>>> references, Set<String> variables) {
\r
133 HashMap<ExpressionField ,ArrayList<Position>> result = new HashMap<ExpressionField ,ArrayList<Position>>();
\r
134 for(String s : variables) {
\r
135 List<Token> tlist = new ArrayList<Token>();
\r
136 for(ExpressionField ef : references.keySet()) {
\r
137 ArrayList<Position> positions = new ArrayList<Position>();
\r
138 tlist = references.get(ef).get(s);
\r
140 for(Token t : tlist) {
\r
141 StyledText st = ef.getSourceViewer().getTextWidget();
\r
142 int start = st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1;
\r
143 int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start;
\r
144 positions.add(new Position(
\r
148 if(result.keySet().contains(ef)) {
\r
149 result.get(ef).addAll((ArrayList<Position>)positions.clone());
\r
151 result.put(ef, (ArrayList<Position>)positions.clone());
\r