1 /*******************************************************************************
\r
2 * Copyright (c) 2010 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.sysdyn.ui.properties.widgets.expressions;
\r
14 import java.io.StringReader;
\r
15 import java.util.ArrayList;
\r
16 import java.util.HashMap;
\r
17 import java.util.HashSet;
\r
18 import java.util.List;
\r
19 import java.util.Set;
\r
21 import org.eclipse.jface.text.Position;
\r
22 import org.eclipse.swt.custom.StyledText;
\r
23 import org.eclipse.swt.graphics.Color;
\r
24 import org.eclipse.swt.widgets.TableItem;
\r
25 import org.simantics.db.Resource;
\r
26 import org.simantics.db.exception.DatabaseException;
\r
27 import org.simantics.sysdyn.expressionParser.ExpressionParser;
\r
28 import org.simantics.sysdyn.expressionParser.ParseException;
\r
29 import org.simantics.sysdyn.expressionParser.Token;
\r
30 import org.simantics.sysdyn.expressionParser.TokenMgrError;
\r
31 import org.simantics.sysdyn.manager.SysdynModel;
\r
32 import org.simantics.sysdyn.manager.SysdynModelManager;
\r
33 import org.simantics.sysdyn.representation.Configuration;
\r
34 import org.simantics.sysdyn.representation.IElement;
\r
35 import org.simantics.sysdyn.representation.Variable;
\r
36 import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;
\r
37 import org.simantics.ui.SimanticsUI;
\r
39 public class ExpressionUtils {
\r
42 * Determines if the given expression is a parameter expression. Parameters are numbers.
\r
43 * If the expression contains anything other than numbers, it is not a parameter.
\r
45 * @param expression The expression to be checked
\r
46 * @return is the expression a parameter
\r
48 static public boolean isParameter(String expression) {
\r
50 Double.parseDouble(expression);
\r
52 } catch (NumberFormatException e) {
\r
57 static public void validateExpressionFields(IExpression expression, TableItem[] connectedVariables, Resource configuration) {
\r
58 ExpressionParser parser = new ExpressionParser(new StringReader(""));
\r
59 Set<String> variables = new HashSet<String>();
\r
60 HashMap<ExpressionField, HashMap<String, List<Token>>> references = new HashMap<ExpressionField, HashMap<String, List<Token>>>();
\r
63 // Build references and variable array
\r
64 for(ExpressionField ef : expression.getExpressionFields()) {
\r
65 ef.resetAnnotations();
\r
66 String textString = ef.getExpression();
\r
67 parser.ReInit(new StringReader(textString));
\r
70 HashMap<String, List<Token>> cr = parser.getReferences();
\r
71 references.put(ef, cr);
\r
72 for(String t : cr.keySet())
\r
74 } catch (ParseException e1) {
\r
75 ef.setSyntaxError(e1.currentToken, "Syntax Error");
\r
76 } catch (TokenMgrError err) {
\r
77 ef.setSyntaxError(0, textString.length(), "MissingLink", "Expression contains unsupported characters");
\r
81 // Remove variables from variable array that don't exist in the model. Create annotations
\r
82 if(!variables.isEmpty()) {
\r
83 ArrayList<String> modelVariables = new ArrayList<String>();
\r
84 Set<String> noSuchVariables = new HashSet<String>();
\r
85 SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());
\r
86 SysdynModel model = sdm.getModel(configuration);
\r
89 } catch (DatabaseException e1) {
\r
90 e1.printStackTrace();
\r
92 Configuration conf = model.getConfiguration();
\r
93 ArrayList<IElement> elements = conf.getElements();
\r
94 for(IElement e : elements) {
\r
95 if(e instanceof Variable) {
\r
96 Variable v = (Variable) e;
\r
97 modelVariables.add(v.getName());
\r
102 for(String v : variables) {
\r
103 if(!modelVariables.contains(v)) {
\r
104 noSuchVariables.add(v);
\r
108 if(!noSuchVariables.isEmpty()) {
\r
109 // remove no such variables from variable list
\r
110 for(String s : noSuchVariables)
\r
111 variables.remove(s);
\r
112 // create annotations
\r
113 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, noSuchVariables);
\r
114 for(ExpressionField ef : positions.keySet()) {
\r
115 ef.setNoSuchVariableAnnotations(positions.get(ef));
\r
120 // Check that the variables that exist have connections and the connected variables have references in the expressions
\r
121 if(!(expression instanceof StockExpression)) {
\r
122 for(TableItem ti : connectedVariables) {
\r
123 if(!variables.contains(ti.getText())) {
\r
124 ti.setForeground(new Color(ti.getDisplay(), 255, 0, 0));
\r
126 ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));
\r
127 variables.remove(ti.getText());
\r
131 if(!variables.isEmpty()) {
\r
132 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, variables);
\r
133 for(ExpressionField ef : positions.keySet()) {
\r
134 ef.setMissingLinkAnnotations(positions.get(ef));
\r
142 @SuppressWarnings("unchecked")
\r
143 static private HashMap<ExpressionField ,ArrayList<Position>> getPositionsForVariables(HashMap<ExpressionField, HashMap<String, List<Token>>> references, Set<String> variables) {
\r
144 HashMap<ExpressionField ,ArrayList<Position>> result = new HashMap<ExpressionField ,ArrayList<Position>>();
\r
145 for(String s : variables) {
\r
146 List<Token> tlist = new ArrayList<Token>();
\r
147 for(ExpressionField ef : references.keySet()) {
\r
148 ArrayList<Position> positions = new ArrayList<Position>();
\r
149 tlist = references.get(ef).get(s);
\r
151 for(Token t : tlist) {
\r
152 StyledText st = ef.getSourceViewer().getTextWidget();
\r
153 int start = st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1;
\r
154 int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start;
\r
155 positions.add(new Position(
\r
159 if(result.keySet().contains(ef)) {
\r
160 result.get(ef).addAll((ArrayList<Position>)positions.clone());
\r
162 result.put(ef, (ArrayList<Position>)positions.clone());
\r