]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
cbf98765b0c22d0b234bc2921507716d1676d754
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\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
13 \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
20 \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
38 \r
39 public class ExpressionUtils {\r
40         \r
41         /**\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
44          * \r
45          * @param expression The expression to be checked\r
46          * @return is the expression a parameter\r
47          */\r
48         static public boolean isParameter(String expression) {\r
49                 try {\r
50                         Double.parseDouble(expression);\r
51                         return true;\r
52                 } catch (NumberFormatException e) {\r
53                         return false;\r
54                 }\r
55         }\r
56 \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
61 \r
62 \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
68             try {\r
69                 parser.expr();\r
70                 HashMap<String, List<Token>> cr = parser.getReferences();\r
71                 references.put(ef, cr);\r
72                 for(String t : cr.keySet())\r
73                     variables.add(t);\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
78             }\r
79         }\r
80 \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
87             try {\r
88                 model.update();\r
89             } catch (DatabaseException e1) {\r
90                 e1.printStackTrace();\r
91             }\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
98                 }\r
99             }\r
100 \r
101 \r
102             for(String v : variables) {\r
103                 if(!modelVariables.contains(v)) {\r
104                     noSuchVariables.add(v);\r
105                 }\r
106             }\r
107 \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
116                 }\r
117             }      \r
118         }\r
119 \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
125                 } else {\r
126                     ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));\r
127                     variables.remove(ti.getText());\r
128                 }\r
129             }\r
130 \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
135                 }\r
136 \r
137             }\r
138         } \r
139 \r
140     }\r
141 \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
150                 if(tlist != null)\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
156                                 start,\r
157                                 offset));\r
158                     }\r
159                 if(result.keySet().contains(ef)) {\r
160                     result.get(ef).addAll((ArrayList<Position>)positions.clone());\r
161                 } else {\r
162                     result.put(ef, (ArrayList<Position>)positions.clone());\r
163                 }\r
164             }\r
165         }\r
166         return result;\r
167     }\r
168 }\r