]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java
Merged changes from feature/scl to master.
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphPropertyRelation.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.common.names.Names;\r
6 import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;\r
7 import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
8 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;\r
9 import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;\r
12 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;\r
13 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;\r
14 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;\r
15 import org.simantics.scl.compiler.environment.Environment;\r
16 import org.simantics.scl.compiler.errors.Locations;\r
17 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
18 import org.simantics.scl.compiler.types.TVar;\r
19 import org.simantics.scl.compiler.types.Type;\r
20 import org.simantics.scl.compiler.types.Types;\r
21 \r
22 public class GraphPropertyRelation implements SCLRelation {\r
23 \r
24     Resource propertyRelation;\r
25     Type valueType;\r
26     Type[] parameterTypes;\r
27 \r
28     private static final Type RESOURCE = Types.con("Simantics/DB", "Resource");\r
29     \r
30     public GraphPropertyRelation(Resource propertyRelation, Type valueType) {\r
31         this.propertyRelation = propertyRelation;\r
32         this.valueType = valueType;\r
33         this.parameterTypes = new Type[] { RESOURCE, valueType };\r
34     }\r
35 \r
36     @Override\r
37     public TVar[] getTypeVariables() {\r
38         return TVar.EMPTY_ARRAY;\r
39     }\r
40     \r
41     @Override\r
42     public Type[] getParameterTypes() {\r
43         return parameterTypes;\r
44     }\r
45 \r
46     @Override\r
47     public double getSelectivity(int boundVariables) {\r
48         switch(boundVariables) {\r
49         case FF:\r
50         case FB: return Double.POSITIVE_INFINITY;\r
51         case BF: return 1.0;\r
52         case BB: return 0.01;\r
53         default: throw new IllegalArgumentException();\r
54         }\r
55     }\r
56     \r
57     @Override\r
58     public int getRequiredVariablesMask() {\r
59         return BF;\r
60     }\r
61     \r
62     private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue");\r
63     \r
64     @Override\r
65     public void generate(long location, QueryCompilationContext context,\r
66             Type[] typeParameters, Variable[] parameters, int boundVariables) {\r
67         Expression possibleValue = new EApply(\r
68                 Locations.NO_LOCATION,\r
69                 Types.READ_GRAPH,\r
70                 context.getCompilationContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),\r
71                 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),\r
72                 new EVariable(parameters[0]),\r
73                 new EExternalConstant(propertyRelation, RESOURCE)\r
74                 );\r
75         switch(boundVariables) {\r
76         case BB: {\r
77             Variable temp = new Variable("temp", valueType);\r
78             context.condition(new EApply(\r
79                     context.getCompilationContext().getConstant(Names.Builtin_equals, valueType),\r
80                     new Expression[] {\r
81                         new EVariable(temp),\r
82                         new EVariable(parameters[1])\r
83                     }\r
84                     ));\r
85             context.iterateMaybe(temp, possibleValue);\r
86         } break;\r
87         case BF: context.iterateMaybe(parameters[1], possibleValue);\r
88         break;\r
89         default: throw new IllegalArgumentException();\r
90         }\r
91     }\r
92 \r
93     private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue");\r
94     \r
95     @Override\r
96     public Expression generateEnforce(long location, EnforcingContext context,\r
97             Type[] typeParameters, Variable[] parameters) {\r
98         return new EApply(\r
99                 Locations.NO_LOCATION,\r
100                 Types.WRITE_GRAPH,\r
101                 context.getCompilationContext().getConstant(CLAIM_RELATED_VALUE, valueType),\r
102                 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),\r
103                 new EVariable(parameters[0]),\r
104                 new EExternalConstant(propertyRelation, RESOURCE),\r
105                 new EVariable(parameters[1])\r
106                 );\r
107     }\r
108 \r
109     @Override\r
110     public int getPhase() {\r
111         return 0;\r
112     }\r
113     \r
114     @Override\r
115     public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters) {\r
116         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support enforce.");\r
117     }\r
118     \r
119     @Override\r
120     public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,\r
121             Expression[] expressions) {\r
122         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support iterate.");\r
123     }\r
124 }\r