]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.mapping/src/org/simantics/mapping/rule/instructions/QueryRuleInstruction.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.mapping / src / org / simantics / mapping / rule / instructions / QueryRuleInstruction.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.mapping.rule.instructions;\r
13 \r
14 import gnu.trove.map.hash.TIntIntHashMap;\r
15 import gnu.trove.procedure.TIntProcedure;\r
16 import gnu.trove.set.hash.TIntHashSet;\r
17 \r
18 import org.simantics.db.ReadGraph;\r
19 import org.simantics.db.WriteGraph;\r
20 import org.simantics.db.exception.DatabaseException;\r
21 import org.simantics.db.request.Read;\r
22 import org.simantics.layer0.utils.triggers.IModification;\r
23 \r
24 public class QueryRuleInstruction implements IRuleInstruction {\r
25 \r
26         IRuleInstruction rule;\r
27         int[] variables;\r
28         int workSpace;\r
29 \r
30         public QueryRuleInstruction(IRuleInstruction rule) {\r
31                 this.rule = rule;\r
32                 TIntHashSet reads = new TIntHashSet();\r
33                 TIntHashSet writes = new TIntHashSet();\r
34                 rule.collectVariables(reads, writes);\r
35                 reads.removeAll(writes.toArray());\r
36                 variables = reads.toArray();\r
37                 final TIntIntHashMap map = new TIntIntHashMap();\r
38                 for(int i = 0;i<variables.length;++i)\r
39                         map.put(variables[i], i);\r
40                 workSpace = variables.length;\r
41                 writes.forEach(new TIntProcedure() {\r
42 \r
43                         @Override\r
44                         public boolean execute(int arg0) {\r
45                                 map.put(arg0, workSpace++);\r
46                                 return true;\r
47                         }\r
48                         \r
49                 });\r
50                 rule.mapVariables(map);\r
51         }\r
52 \r
53         @Override\r
54         public void collectVariables(TIntHashSet reads, TIntHashSet writes) {\r
55                 reads.addAll(variables);\r
56         }\r
57 \r
58         class Query implements Read<IModification> {\r
59 \r
60                 Object[] parameters;\r
61                 \r
62                 public Query(Object[] parameters) {\r
63                         this.parameters = parameters;\r
64                 }\r
65 \r
66                 QueryRuleInstruction parent() {\r
67                         return QueryRuleInstruction.this;\r
68                 }\r
69                 \r
70                 @Override\r
71                 public boolean equals(Object other) {\r
72                         if(this == other)\r
73                                 return true;\r
74                         if(other == null || other.getClass() != this.getClass())\r
75                                 return false;\r
76                         Query q = (Query)other;\r
77                         if(!parent().equals(q.parent()))\r
78                                 return false;\r
79                         if(parameters.length != q.parameters.length)\r
80                                 return false;\r
81                         for(int i=0;i<parameters.length;++i)\r
82                                 if(parameters[i] == null ? q.parameters[i] != null : !parameters[i].equals(q.parameters[i]))\r
83                                         return false;\r
84                         return true;\r
85                 }\r
86 \r
87                 @Override\r
88                 public int hashCode() {\r
89                         int result = QueryRuleInstruction.this.hashCode();\r
90                         for(Object parameter : parameters) {\r
91                                 result *= 31;\r
92                                 if(parameter != null)\r
93                                         result += parameter.hashCode();\r
94                                 else\r
95                                         System.err.println("Parameter is null!!!");\r
96                         }\r
97                         return result;\r
98                 }\r
99 \r
100                 @Override\r
101                 public IModification perform(ReadGraph g) throws DatabaseException {                    \r
102                         final Object[] bindings = new Object[workSpace];\r
103                         System.arraycopy(parameters, 0, bindings, 0, parameters.length);\r
104                         return rule.execute(g, bindings);                       \r
105                 }\r
106                 \r
107         }\r
108         \r
109         @Override\r
110         public IModification execute(ReadGraph g, Object[] bindings) throws DatabaseException {\r
111                 Object[] parameters = new Object[variables.length];\r
112                 for(int i=0;i<variables.length;++i)\r
113                         parameters[i] = bindings[variables[i]];\r
114                 IModification result = g.syncRequest(new Query(parameters));\r
115                 return result;\r
116         }\r
117 \r
118         @Override\r
119         public void doExecute(WriteGraph g, Object[] bindings) throws DatabaseException {\r
120                 Object[] parameters = new Object[variables.length];\r
121                 for(int i=0;i<variables.length;++i)\r
122                         parameters[i] = bindings[variables[i]];\r
123                 IModification modi = g.syncRequest(new Query(parameters));\r
124                 if(modi != null)\r
125                         modi.perform(g);\r
126         }\r
127         \r
128         @Override\r
129         public void mapVariables(TIntIntHashMap map) {\r
130                 for(int i=0;i<variables.length;++i)\r
131                         variables[i] = map.get(variables[i]);           \r
132         }\r
133         \r
134         @Override\r
135         public void toString(StringBuilder b, int indent) {\r
136                 b.append("QUERY[");\r
137                 b.append(workSpace);\r
138                 b.append("]");\r
139                 for(int i=0;i<variables.length;++i)\r
140                         b.append(" " + variables[i] + "->" + i);\r
141                 b.append('\n');\r
142                 for(int i=0;i<indent;++i)\r
143                         b.append(INDENTATION);\r
144                 rule.toString(b, indent);\r
145         }\r
146         \r
147 }\r