Merge "Remove unnecessary getComparableKey from HashMapBinding"
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / scl / CompileStructuralValueRequest.java
1 package org.simantics.structural2.scl;
2
3 import org.simantics.databoard.Bindings;
4 import org.simantics.db.ReadGraph;
5 import org.simantics.db.Resource;
6 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
7 import org.simantics.db.common.request.IndexRoot;
8 import org.simantics.db.exception.DatabaseException;
9 import org.simantics.db.layer0.variable.Variable;
10 import org.simantics.layer0.Layer0;
11 import org.simantics.scl.runtime.SCLContext;
12 import org.simantics.scl.runtime.function.Function1;
13
14 /**
15  * Compiles an SCL expression that is attached to a literal
16  * whose parent is a component that is a part of a component type.
17  * 
18  * @author Hannu Niemistö
19  */
20 public class CompileStructuralValueRequest extends AbstractCompileStructuralValueRequest {
21     
22     protected final Resource component;
23     protected final Resource literal;
24     
25     public CompileStructuralValueRequest(Resource component, Resource literal, Resource relation) {
26         super(relation);
27         this.component = component;
28         this.literal = literal;
29     }
30     
31     public CompileStructuralValueRequest(ReadGraph graph, Variable context) throws DatabaseException {
32         this(context.getParent(graph).getRepresents(graph),
33                 context.getRepresents(graph),
34                 context.getPredicateResource(graph));
35     }
36     
37     public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
38         SCLContext sclContext = SCLContext.getCurrent();
39         Object oldGraph = sclContext.get("graph");
40         CompileStructuralValueRequest request = new CompileStructuralValueRequest(graph, context);
41         try {
42             Function1<Object,Object> exp = graph.syncRequest(request, TransientCacheListener.instance());
43             sclContext.put("graph", graph);
44             return exp.apply(context);
45         } catch (Throwable t) {
46             throw new DatabaseException("Compiling structural value request for component=" + request.component + ", literal=" + request.literal + " and relation " + request.relation + " failed!", t);
47         } finally {
48             sclContext.put("graph", oldGraph);
49         }
50     }
51     
52     public static Function1<Object, Object> compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
53         return graph.syncRequest(new CompileStructuralValueRequest(s, o, p), TransientCacheListener.instance());
54     }
55     
56     @Override
57     protected String getExpressionText(ReadGraph graph)
58             throws DatabaseException {
59         Layer0 L0 = Layer0.getInstance(graph);
60         return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
61     }
62
63     @Override
64     protected Resource getIndexRoot(ReadGraph graph) throws DatabaseException {
65         return graph.syncRequest(new IndexRoot(literal));
66     }
67
68     @Override
69     protected Resource getComponentType(ReadGraph graph)
70                 throws DatabaseException {
71         // This is possible e.g. for interface expressions inside procedurals
72         if(component == null) return null;
73         return graph.syncRequest(new FindPossibleComponentTypeRequest(component));
74     }
75
76         @Override
77         public int hashCode() {
78                 final int prime = 31;
79                 int result = 1;
80                 result = prime * result + ((relation == null) ? 0 : relation.hashCode());
81                 result = prime * result + ((component == null) ? 0 : component.hashCode());
82                 result = prime * result + ((literal == null) ? 0 : literal.hashCode());
83                 return result;
84         }
85
86         @Override
87         public boolean equals(Object obj) {
88                 if (this == obj)
89                         return true;
90                 if (obj == null)
91                         return false;
92                 if (getClass() != obj.getClass())
93                         return false;
94                 CompileStructuralValueRequest other = (CompileStructuralValueRequest) obj;
95                 if (relation == null) {
96                         if (other.relation != null)
97                                 return false;
98                 } else if (!relation.equals(other.relation))
99                         return false;
100                 if (component == null) {
101                         if (other.component != null)
102                                 return false;
103                 } else if (!component.equals(other.component))
104                         return false;
105                 if (literal == null) {
106                         if (other.literal != null)
107                                 return false;
108                 } else if (!literal.equals(other.literal))
109                         return false;
110                 return true;
111         }
112         
113 }