1 package org.simantics.scl.commands.internal;
\r
3 import org.simantics.db.ReadGraph;
\r
4 import org.simantics.db.RequestProcessor;
\r
5 import org.simantics.db.Resource;
\r
6 import org.simantics.db.WriteGraph;
\r
7 import org.simantics.db.common.request.WriteResultRequest;
\r
8 import org.simantics.db.exception.DatabaseException;
\r
9 import org.simantics.db.procedure.Procedure;
\r
10 import org.simantics.db.request.Read;
\r
11 import org.simantics.scl.commands.Command;
\r
12 import org.simantics.scl.commands.internal.checker.Checker;
\r
13 import org.simantics.scl.commands.internal.serialization.CommandSerializer;
\r
14 import org.simantics.scl.commands.internal.serialization.CommandSerializerFactory;
\r
15 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
\r
16 import org.simantics.scl.compiler.top.ValueNotFound;
\r
17 import org.simantics.scl.compiler.types.Type;
\r
18 import org.simantics.scl.compiler.types.Types;
\r
19 import org.simantics.scl.compiler.types.util.MultiFunction;
\r
20 import org.simantics.scl.osgi.SCLOsgi;
\r
21 import org.simantics.scl.runtime.SCLContext;
\r
22 import org.simantics.scl.runtime.function.Function;
\r
23 import org.simantics.utils.logging.TimeLogger;
\r
26 * Default command implementation
\r
28 * @author Hannu Niemistö
\r
30 @SuppressWarnings({"rawtypes", "restriction"})
\r
31 public class CommandImpl implements Command {
\r
35 Type[] parameterTypes;
\r
36 CommandSerializer serializer;
\r
39 public CommandImpl(String name, Function command, Type[] parameterTypes,
\r
40 CommandSerializer serializer, Checker checker) {
\r
42 this.command = command;
\r
43 this.parameterTypes = parameterTypes;
\r
44 this.serializer = serializer;
\r
45 this.checker = checker;
\r
48 private class CheckRequest implements Read<Boolean> {
\r
49 Object[] parameters;
\r
51 public CheckRequest(Object[] parameters) {
\r
52 this.parameters = parameters;
\r
56 public Boolean perform(ReadGraph graph) throws DatabaseException {
\r
57 SCLContext sclContext = SCLContext.getCurrent();
\r
58 Object oldGraph = sclContext.put("graph", graph);
\r
59 boolean result = checker.check(parameters);
\r
60 sclContext.put("graph", oldGraph);
\r
66 public boolean check(RequestProcessor processor, Resource model,
\r
67 Object... parameters) throws DatabaseException {
\r
68 CheckRequest request = new CheckRequest(parameters);
\r
69 if(processor instanceof ReadGraph)
\r
70 return request.perform((ReadGraph)processor);
\r
72 return processor.syncRequest(request);
\r
75 private static boolean serializationErrorAlreadySeen = false;
\r
77 private class CommitRequest extends WriteResultRequest<Object> {
\r
79 Object[] parameters;
\r
81 public CommitRequest(Resource model, Object[] parameters) {
\r
83 this.parameters = parameters;
\r
87 public Object perform(WriteGraph graph) throws DatabaseException {
\r
88 SCLContext sclContext = SCLContext.getCurrent();
\r
89 Object oldGraph = sclContext.put("graph", graph);
\r
90 // Serialize command first
\r
92 serializer.serialize(graph, model, parameters);
\r
93 } catch(Exception e) {
\r
94 if(!serializationErrorAlreadySeen) {
\r
95 e.printStackTrace();
\r
96 serializationErrorAlreadySeen = true;
\r
100 // Then execute (otherwise target of the command might not exist anymore)
\r
102 return command.applyArray(parameters);
\r
104 sclContext.put("graph", oldGraph);
\r
111 public Object execute(RequestProcessor processor, Resource model, Object ... parameters) throws DatabaseException {
\r
112 if(parameters.length != parameterTypes.length)
\r
113 throw new IllegalArgumentException("Wrong number of parameters given (" + parameters.length + ") expected " +
\r
114 parameterTypes.length + " parameters.");
\r
115 CommitRequest request = new CommitRequest(model, parameters);
\r
117 if(processor instanceof WriteGraph)
\r
118 return request.perform((WriteGraph)processor);
\r
120 return processor.syncRequest(request);
\r
122 TimeLogger.log("Executed command " + name);
\r
127 public void asyncExecute(RequestProcessor processor, Resource model,
\r
128 Object[] parameters, Procedure<Object> procedure) {
\r
129 processor.asyncRequest(new CommitRequest(model, parameters), procedure);
\r
132 public static Command create(ReadGraph graph, String name) {
\r
133 Object oldGraph = SCLContext.getCurrent().put("graph", graph);
\r
135 SCLValue commandRef = SCLOsgi.MODULE_REPOSITORY.getValueRef(name);
\r
136 MultiFunction mfun = Types.matchFunction(commandRef.getType());
\r
137 Type[] parameterTypes = mfun.parameterTypes;
\r
138 Function command = (Function)SCLOsgi.MODULE_REPOSITORY.getValue(name);
\r
139 CommandSerializer serializer = CommandSerializerFactory.create(name, parameterTypes);
\r
140 Checker checker = Checker.create(name + "_check");
\r
141 return new CommandImpl(name, command, parameterTypes, serializer, checker);
\r
142 } catch(ValueNotFound e) {
\r
143 e.printStackTrace();
\r
144 return new ErrorCommand(name);
\r
146 SCLContext.getCurrent().put("graph", oldGraph);
\r