package org.simantics.modeling; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.request.Read; import org.simantics.scl.compiler.environment.LocalEnvironment; import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; import org.simantics.scl.compiler.errors.CompilationError; import org.simantics.scl.compiler.errors.ErrorSeverity; import org.simantics.scl.compiler.module.repository.ImportFailure; import org.simantics.scl.compiler.module.repository.ImportFailureException; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.scl.compiler.top.ExpressionEvaluator; import org.simantics.scl.compiler.top.SCLExpressionCompilationException; import org.simantics.structural.stubs.StructuralResource2; public class ComponentTypeScriptRequest implements Read { private Resource script; private Resource componentType; public ComponentTypeScriptRequest(Resource script, Resource componentType) { this.script = script; this.componentType = componentType; } @Override public ComponentTypeScriptResult perform(ReadGraph graph) throws DatabaseException { IComponentTypeScriptEnvironmentFactory factory = graph.adapt(componentType, IComponentTypeScriptEnvironmentFactory.class); EnvironmentSpecification spec = factory.getRuntimeEnvironmentSpecification(graph, componentType); RuntimeEnvironment runtime; try { runtime = graph.syncRequest(new ComponentTypeScriptRuntimeEnvironmentRequest(spec)); } catch (DatabaseException e) { if (e.getCause() instanceof ImportFailureException) { ImportFailureException cause = (ImportFailureException)e.getCause(); // if one of the scl modules can not be imported just show an error // at the very start of the editor List errors = new ArrayList(); for (ImportFailure failure : cause.failures) { errors.add(new CompilationError(0, failure.toString(), failure.reason == ImportFailure.MODULE_DOES_NOT_EXIST_REASON ? ErrorSeverity.ERROR : ErrorSeverity.IMPORT_ERROR)); } return new ComponentTypeScriptResult(errors, null); } else { throw e; } } StructuralResource2 str = StructuralResource2.getInstance(graph); String code = graph.getRelatedValue(script, str.ComponentTypeScript_code, Bindings.STRING); ExpressionEvaluator eval = new ExpressionEvaluator(runtime, code); eval.interpretIfPossible(false).parseAsBlock(true); // set the local environment if necessary LocalEnvironment local = factory.getLocalEnvironment(graph, componentType); if (local != null) eval.localEnvironment(local); Object result; try { result = eval.eval(); } catch (SCLExpressionCompilationException e) { return new ComponentTypeScriptResult(Arrays.asList(e.getErrors()), null); } return new ComponentTypeScriptResult(Collections.emptyList(), result, factory.getModuleReads(local), factory.getModuleWrites(local)); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((componentType == null) ? 0 : componentType.hashCode()); result = prime * result + ((script == null) ? 0 : script.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; ComponentTypeScriptRequest other = (ComponentTypeScriptRequest) obj; if (componentType == null) { if (other.componentType != null) return false; } else if (!componentType.equals(other.componentType)) return false; if (script == null) { if (other.script != null) return false; } else if (!script.equals(other.script)) return false; return true; } }