53b601fa2820ea91c640a42d643daff539ca343d
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / ComponentTypeScriptRequest.java
1 package org.simantics.modeling;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.List;
7
8 import org.simantics.databoard.Bindings;
9 import org.simantics.db.ReadGraph;
10 import org.simantics.db.Resource;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.db.request.Read;
13 import org.simantics.scl.compiler.environment.LocalEnvironment;
14 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
15 import org.simantics.scl.compiler.errors.CompilationError;
16 import org.simantics.scl.compiler.module.repository.ImportFailure;
17 import org.simantics.scl.compiler.module.repository.ImportFailureException;
18 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
19 import org.simantics.scl.compiler.top.ExpressionEvaluator;
20 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
21 import org.simantics.structural.stubs.StructuralResource2;
22
23 public class ComponentTypeScriptRequest implements Read<ComponentTypeScriptResult> {
24
25     private Resource script;
26     private Resource componentType;
27
28     public ComponentTypeScriptRequest(Resource script, Resource componentType) {
29         this.script = script;
30         this.componentType = componentType;
31     }
32     
33     @Override
34     public ComponentTypeScriptResult perform(ReadGraph graph) throws DatabaseException {
35         IComponentTypeScriptEnvironmentFactory factory = graph.adapt(componentType, IComponentTypeScriptEnvironmentFactory.class);
36
37         EnvironmentSpecification spec = factory.getRuntimeEnvironmentSpecification(graph, componentType);
38         
39         RuntimeEnvironment runtime;
40         try {
41             runtime = graph.syncRequest(new ComponentTypeScriptRuntimeEnvironmentRequest(spec));
42         }
43         catch (DatabaseException e) {
44             if (e.getCause() instanceof ImportFailureException) {
45                 ImportFailureException cause = (ImportFailureException)e.getCause();
46                 // if one of the scl modules can not be imported just show an error
47                 // at the very start of the editor
48                 List<CompilationError> errors = new ArrayList<CompilationError>();
49                 for (ImportFailure failure : cause.failures) {
50                     errors.add(new CompilationError(0, failure.toString()));
51                 }
52                 return new ComponentTypeScriptResult(errors, null);
53             }
54             else {
55                 throw e;
56             }
57         }
58         
59         StructuralResource2 str = StructuralResource2.getInstance(graph);
60         String code = graph.getRelatedValue(script, str.ComponentTypeScript_code, Bindings.STRING);
61         
62         ExpressionEvaluator eval = new ExpressionEvaluator(runtime, code);
63         eval.interpretIfPossible(false).parseAsBlock(true);
64         
65         // set the local environment if necessary
66         LocalEnvironment local = factory.getLocalEnvironment(graph, componentType);
67         if (local != null)
68             eval.localEnvironment(local);
69         
70         Object result;
71         try {
72             result = eval.eval();
73         }
74         catch (SCLExpressionCompilationException e) {
75             return new ComponentTypeScriptResult(Arrays.asList(e.getErrors()), null);
76         }
77         
78         return new ComponentTypeScriptResult(Collections.<CompilationError>emptyList(), 
79                                              result, 
80                                              factory.getModuleReads(local), 
81                                              factory.getModuleWrites(local));
82     }
83     
84     @Override
85     public int hashCode() {
86         final int prime = 31;
87         int result = 1;
88         result = prime * result
89                 + ((componentType == null) ? 0 : componentType.hashCode());
90         result = prime * result + ((script == null) ? 0 : script.hashCode());
91         return result;
92     }
93
94     @Override
95     public boolean equals(Object obj) {
96         if (this == obj)
97             return true;
98         if (obj == null)
99             return false;
100         if (getClass() != obj.getClass())
101             return false;
102         ComponentTypeScriptRequest other = (ComponentTypeScriptRequest) obj;
103         if (componentType == null) {
104             if (other.componentType != null)
105                 return false;
106         } else if (!componentType.equals(other.componentType))
107             return false;
108         if (script == null) {
109             if (other.script != null)
110                 return false;
111         } else if (!script.equals(other.script))
112             return false;
113         return true;
114     }
115
116 }