]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
2b11a3026f342dc979e2f2545929139f03f84664
[simantics/sysdyn.git] /
1 package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
2 \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
9 \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
27 \r
28 public class ExpressionUtils {\r
29         \r
30         /**\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
33          * \r
34          * @param expression The expression to be checked\r
35          * @return is the expression a parameter\r
36          */\r
37         static public boolean isParameter(String expression) {\r
38                 try {\r
39                         Double.parseDouble(expression);\r
40                         return true;\r
41                 } catch (NumberFormatException e) {\r
42                         return false;\r
43                 }\r
44         }\r
45 \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
50 \r
51 \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
57             try {\r
58                 parser.expr();\r
59                 HashMap<String, List<Token>> cr = parser.getReferences();\r
60                 references.put(ef, cr);\r
61                 for(String t : cr.keySet())\r
62                     variables.add(t);\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
67             }\r
68         }\r
69 \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
76             try {\r
77                 model.update();\r
78             } catch (DatabaseException e1) {\r
79                 e1.printStackTrace();\r
80             }\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
87                 }\r
88             }\r
89 \r
90 \r
91             for(String v : variables) {\r
92                 if(!modelVariables.contains(v)) {\r
93                     noSuchVariables.add(v);\r
94                 }\r
95             }\r
96 \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
105                 }\r
106             }      \r
107         }\r
108 \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
114                 } else {\r
115                     ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));\r
116                     variables.remove(ti.getText());\r
117                 }\r
118             }\r
119 \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
124                 }\r
125 \r
126             }\r
127         } \r
128 \r
129     }\r
130 \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
139                 if(tlist != null)\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
145                                 start,\r
146                                 offset));\r
147                     }\r
148                 if(result.keySet().contains(ef)) {\r
149                     result.get(ef).addAll((ArrayList<Position>)positions.clone());\r
150                 } else {\r
151                     result.put(ef, (ArrayList<Position>)positions.clone());\r
152                 }\r
153             }\r
154         }\r
155         return result;\r
156     }\r
157 }\r