]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
Ensure GetElementClassRequest is not constructed without elementFactory
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphRelation.java
1 package org.simantics.modeling.scl;\r
2 \r
3 import org.simantics.db.Resource;\r
4 import org.simantics.scl.compiler.common.names.Name;\r
5 import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
6 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
7 import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
8 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
9 import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
10 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;\r
11 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;\r
12 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
13 import org.simantics.scl.compiler.errors.Locations;\r
14 import org.simantics.scl.compiler.types.TVar;\r
15 import org.simantics.scl.compiler.types.Type;\r
16 import org.simantics.scl.compiler.types.Types;\r
17 \r
18 public class GraphRelation implements SCLRelation {\r
19 \r
20     Resource relation;\r
21     double relationSelectivity;\r
22     Resource inverseRelation;\r
23     double inverseRelationSelectivity;\r
24     \r
25     public GraphRelation(Resource relation, double relationSelectivity,\r
26             Resource inverseRelation, double inverseRelationSelectivity) {\r
27         this.relation = relation;\r
28         this.relationSelectivity = relationSelectivity;\r
29         this.inverseRelation = inverseRelation;\r
30         this.inverseRelationSelectivity = inverseRelationSelectivity;\r
31     }\r
32 \r
33     @Override\r
34     public TVar[] getTypeVariables() {\r
35         return TVar.EMPTY_ARRAY;\r
36     }\r
37     \r
38     private static final Type[] PARAMETER_TYPES = new Type[] { Types.RESOURCE, Types.RESOURCE };\r
39     \r
40     @Override\r
41     public Type[] getParameterTypes() {\r
42         return PARAMETER_TYPES;\r
43     }\r
44 \r
45     @Override\r
46     public double getSelectivity(int boundVariables) {\r
47         switch(boundVariables) {\r
48         case FF: return Double.POSITIVE_INFINITY;\r
49         case BF: return relationSelectivity;\r
50         case FB: return inverseRelation == null ? Double.POSITIVE_INFINITY : inverseRelationSelectivity;\r
51         case BB: return 0.1;\r
52         default: throw new IllegalArgumentException();\r
53         }\r
54     }\r
55     \r
56     @Override\r
57     public int getRequiredVariablesMask() {\r
58         return inverseRelation == null ? BF : FF;\r
59     }\r
60     \r
61     private static final Name GET_OBJECTS = Name.create("Simantics/DB", "#");\r
62     private static final Name HAS_STATEMENT = Name.create("Simantics/DB", "existsStatement3");\r
63     \r
64     @Override\r
65     public void generate(long location, QueryCompilationContext context,\r
66             Type[] typeParameters, Variable[] parameters, int boundVariables) {\r
67         switch(boundVariables) {\r
68         case BF: \r
69             context.iterateList(parameters[1], new EApply(\r
70                     Locations.NO_LOCATION,\r
71                     Types.READ_GRAPH,\r
72                     context.getTypingContext().getConstant(GET_OBJECTS),\r
73                     new EVariable(parameters[0]),\r
74                     new EExternalConstant(relation, Types.RESOURCE)\r
75                     ));\r
76             break;\r
77         case FB:\r
78             if(inverseRelation == null)\r
79                 throw new IllegalArgumentException();\r
80             context.iterateList(parameters[0], new EApply(\r
81                     Locations.NO_LOCATION,\r
82                     Types.READ_GRAPH,\r
83                     context.getTypingContext().getConstant(GET_OBJECTS),\r
84                     new EVariable(parameters[1]),\r
85                     new EExternalConstant(inverseRelation, Types.RESOURCE)\r
86                     ));\r
87             break;\r
88         case BB:\r
89             context.condition(\r
90                     inverseRelation == null || relationSelectivity <= inverseRelationSelectivity\r
91                     ? new EApply(\r
92                             Locations.NO_LOCATION,\r
93                             Types.READ_GRAPH,\r
94                             context.getTypingContext().getConstant(HAS_STATEMENT),\r
95                             new Expression[] {\r
96                                 new EVariable(parameters[0]),\r
97                                 new EExternalConstant(relation, Types.RESOURCE),\r
98                                 new EVariable(parameters[1])\r
99                             }\r
100                             )\r
101                     : new EApply(\r
102                             Locations.NO_LOCATION,\r
103                             Types.READ_GRAPH,\r
104                             context.getTypingContext().getConstant(HAS_STATEMENT),\r
105                             new Expression[] {\r
106                                 new EVariable(parameters[1]),\r
107                                 new EExternalConstant(inverseRelation, Types.RESOURCE),\r
108                                 new EVariable(parameters[0])\r
109                             }\r
110                             ));\r
111             break;\r
112         default: throw new IllegalArgumentException();\r
113         }\r
114     }\r
115 \r
116     private static final Name CLAIM = Name.create("Simantics/DB", "claim");\r
117     \r
118     @Override\r
119     public Expression generateEnforce(long location, EnforcingContext context,\r
120             Type[] typeParameters, Variable[] parameters) {\r
121         return new EApply(\r
122                 Locations.NO_LOCATION,\r
123                 Types.WRITE_GRAPH,\r
124                 context.getTypingContext().getConstant(CLAIM),\r
125                 new EVariable(parameters[0]),\r
126                 new EExternalConstant(relation, Types.RESOURCE),\r
127                 new EVariable(parameters[1])\r
128                 );\r
129     }\r
130 \r
131     @Override\r
132     public int getPhase() {\r
133         return 0;\r
134     }\r
135 \r
136 }\r