]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
92ef23264a6cb01d4e56e64f5a88baa6561ce0c6
[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.sysdyn.expressionParser.ExpressionParser;\r
16 import org.simantics.sysdyn.expressionParser.ParseException;\r
17 import org.simantics.sysdyn.expressionParser.Token;\r
18 import org.simantics.sysdyn.manager.SysdynModel;\r
19 import org.simantics.sysdyn.manager.SysdynModelManager;\r
20 import org.simantics.sysdyn.representation.Configuration;\r
21 import org.simantics.sysdyn.representation.IElement;\r
22 import org.simantics.sysdyn.representation.IndependentVariable;\r
23 import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;\r
24 import org.simantics.ui.SimanticsUI;\r
25 \r
26 public class ExpressionValidation {\r
27 \r
28     static public void validateExpressionFields(IExpression expression, TableItem[] connectedVariables, Resource configuration) {\r
29         ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
30         Set<String> variables = new HashSet<String>();\r
31         HashMap<ExpressionField, HashMap<String, List<Token>>> references = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
32 \r
33 \r
34         // Build references and variable array\r
35         for(ExpressionField ef : expression.getExpressionFields()) {\r
36             ef.resetAnnotations();\r
37             String textString = ef.getExpression();\r
38             parser.ReInit(new StringReader(textString));\r
39             try {\r
40                 parser.expr();\r
41                 HashMap<String, List<Token>> cr = parser.getReferences();\r
42                 references.put(ef, cr);\r
43                 for(String t : cr.keySet())\r
44                     variables.add(t);\r
45             } catch (ParseException e1) {\r
46                 ef.setSyntaxError(e1.currentToken);\r
47             }\r
48         }\r
49 \r
50         // Remove variables from variable array that don't exist in the model. Create annotations\r
51         if(!variables.isEmpty()) {\r
52             ArrayList<String> modelVariables = new ArrayList<String>();\r
53             Set<String> noSuchVariables = new HashSet<String>();\r
54             SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
55             SysdynModel model = sdm.getModel(configuration);\r
56             Configuration conf = model.getConfiguration();\r
57             ArrayList<IElement> elements = conf.getElements();\r
58             for(IElement e : elements) {\r
59                 if(e instanceof IndependentVariable) {\r
60                     IndependentVariable v = (IndependentVariable) e;\r
61                     modelVariables.add(v.getName());\r
62                 }\r
63             }\r
64 \r
65 \r
66             for(String v : variables) {\r
67                 if(!modelVariables.contains(v)) {\r
68                     noSuchVariables.add(v);\r
69                 }\r
70             }\r
71 \r
72             if(!noSuchVariables.isEmpty()) {\r
73                 // remove no such variables from variable list\r
74                 for(String s : noSuchVariables)\r
75                     variables.remove(s);\r
76                 // create annotations\r
77                 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, noSuchVariables);\r
78                 for(ExpressionField ef : positions.keySet()) {\r
79                     ef.setNoSuchVariableAnnotations(positions.get(ef));\r
80                 }\r
81             }      \r
82         }\r
83 \r
84         // Check that the variables that exist have connections and the connected variables have references in the expressions\r
85         if(!(expression instanceof StockExpression)) { \r
86             for(TableItem ti : connectedVariables) {\r
87                 if(!variables.contains(ti.getText())) {\r
88                     ti.setForeground(new Color(ti.getDisplay(), 255, 0, 0));\r
89                 } else {\r
90                     ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));\r
91                     variables.remove(ti.getText());\r
92                 }\r
93             }\r
94 \r
95             if(!variables.isEmpty()) {\r
96                 HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, variables);\r
97                 for(ExpressionField ef : positions.keySet()) {\r
98                     ef.setMissingLinkAnnotations(positions.get(ef));\r
99                 }\r
100 \r
101             }\r
102         } \r
103 \r
104     }\r
105 \r
106     @SuppressWarnings("unchecked")\r
107     static private HashMap<ExpressionField ,ArrayList<Position>> getPositionsForVariables(HashMap<ExpressionField, HashMap<String, List<Token>>> references, Set<String> variables) {\r
108         HashMap<ExpressionField ,ArrayList<Position>> result = new HashMap<ExpressionField ,ArrayList<Position>>();\r
109         for(String s : variables) {\r
110             List<Token> tlist = new ArrayList<Token>();\r
111             for(ExpressionField ef : references.keySet()) {\r
112                 ArrayList<Position> positions = new ArrayList<Position>();\r
113                 tlist = references.get(ef).get(s);\r
114                 if(tlist != null)\r
115                     for(Token t : tlist) {\r
116                         StyledText st = ef.getSourceViewer().getTextWidget();\r
117                         int start =  st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1;\r
118                         int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start;\r
119                         positions.add(new Position(\r
120                                 start,\r
121                                 offset));\r
122                     }\r
123                 if(result.keySet().contains(ef)) {\r
124                     result.get(ef).addAll((ArrayList<Position>)positions.clone());\r
125                 } else {\r
126                     result.put(ef, (ArrayList<Position>)positions.clone());\r
127                 }\r
128             }\r
129         }\r
130         return result;\r
131     }\r
132 }\r