package org.simantics.structural2.scl; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.IndexRoot; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function1; /** * Compiles an SCL expression that is attached to a literal * whose parent is a component that is a part of a component type. * * @author Hannu Niemistö */ public class CompileStructuralValueRequest extends AbstractCompileStructuralValueRequest { protected final Resource component; protected final Resource literal; public CompileStructuralValueRequest(Resource component, Resource literal, Resource relation) { super(relation); this.component = component; this.literal = literal; } public CompileStructuralValueRequest(ReadGraph graph, Variable context) throws DatabaseException { this(context.getParent(graph).getRepresents(graph), context.getRepresents(graph), context.getPredicateResource(graph)); } public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException { SCLContext sclContext = SCLContext.getCurrent(); Object oldGraph = sclContext.get("graph"); CompileStructuralValueRequest request = new CompileStructuralValueRequest(graph, context); try { Function1 exp = graph.syncRequest(request, TransientCacheListener.instance()); sclContext.put("graph", graph); return exp.apply(context); } catch (Throwable t) { throw new DatabaseException("Compiling structural value request for component=" + request.component + ", literal=" + request.literal + " and relation " + request.relation + " failed!", t); } finally { sclContext.put("graph", oldGraph); } } public static Function1 compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException { return graph.syncRequest(new CompileStructuralValueRequest(s, o, p), TransientCacheListener.instance()); } @Override protected String getExpressionText(ReadGraph graph) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); } @Override protected Resource getIndexRoot(ReadGraph graph) throws DatabaseException { return graph.syncRequest(new IndexRoot(literal)); } @Override protected Resource getComponentType(ReadGraph graph) throws DatabaseException { // This is possible e.g. for interface expressions inside procedurals if(component == null) return null; return graph.syncRequest(new FindPossibleComponentTypeRequest(component)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((relation == null) ? 0 : relation.hashCode()); result = prime * result + ((component == null) ? 0 : component.hashCode()); result = prime * result + ((literal == null) ? 0 : literal.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CompileStructuralValueRequest other = (CompileStructuralValueRequest) obj; if (relation == null) { if (other.relation != null) return false; } else if (!relation.equals(other.relation)) return false; if (component == null) { if (other.component != null) return false; } else if (!component.equals(other.component)) return false; if (literal == null) { if (other.literal != null) return false; } else if (!literal.equals(other.literal)) return false; return true; } }