]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/migration/SCLScriptMigrationStep.java
Simple migration step implementation that runs a specified SCL script
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / migration / SCLScriptMigrationStep.java
1 /*******************************************************************************
2  * Copyright (c) 2019 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.modeling.migration;
13
14 import java.io.PrintWriter;
15 import java.io.StringReader;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.simantics.Simantics;
22 import org.simantics.databoard.Bindings;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.Resource;
25 import org.simantics.db.Session;
26 import org.simantics.db.common.utils.NameUtils;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.layer0.migration.MigrationState;
29 import org.simantics.db.layer0.migration.MigrationStateKeys;
30 import org.simantics.db.layer0.migration.MigrationStep;
31 import org.simantics.db.layer0.migration.MigrationUtils;
32 import org.simantics.db.layer0.migration.NullWriter;
33 import org.simantics.db.request.Read;
34 import org.simantics.modeling.ModelingResources;
35 import org.simantics.scl.compiler.commands.CommandSession;
36 import org.simantics.scl.compiler.types.Types;
37 import org.simantics.scl.osgi.SCLOsgi;
38 import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler;
39 import org.simantics.scl.runtime.reporting.SCLReportingHandler;
40
41 /**
42  * Runs the SCL script associated with the migration step.
43  * 
44  * @author Tuukka Lehtonen
45  * @since 1.41.0
46  */
47 public class SCLScriptMigrationStep implements MigrationStep {
48
49     private String scriptId;
50     private String script;
51
52     public SCLScriptMigrationStep(ReadGraph graph, Resource step) throws DatabaseException {
53         this.scriptId = NameUtils.getSafeName(graph, step);
54         this.script = graph.getRelatedValue(
55                 step,
56                 ModelingResources.getInstance(graph).Migration_SCLScriptMigrationStep_script,
57                 Bindings.STRING);
58     }
59
60     @Override
61     public void applyTo(final IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
62         Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
63         if (!roots.isEmpty()) {
64             PrintWriter log = MigrationUtils.getProperty(state, MigrationStateKeys.MESSAGE_LOG_WRITER, NullWriter.PRINT_INSTANCE);
65             runScript(monitor, roots, log);
66         }
67     }
68
69     private static class ReportingHandler extends AbstractSCLReportingHandler {
70         PrintWriter log;
71
72         public ReportingHandler(PrintWriter log) {
73             this.log = log;
74         }
75
76         @Override
77         public void print(String text) {
78             log.println(text);
79         }
80
81         @Override
82         public void printError(String error) {
83             log.println("ERROR: " + error);
84         }
85     }
86
87     private void runScript(IProgressMonitor monitor, Collection<Resource> roots, PrintWriter log) throws DatabaseException {
88         log.format("## Running SCL Script Migration Step `%s` ##%n", scriptId);
89         SCLReportingHandler rh = new ReportingHandler(log);
90         Map<Resource, String> rootNames = mapNames(roots);
91         for (Resource root : roots) {
92             log.format("### Running script for root `%s` ###%n", rootNames.get(root));
93             CommandSession session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, rh);
94             session.setVariable("root", Types.RESOURCE, root);
95             session.execute(new StringReader(script), rh);
96         }
97     }
98
99     private Map<Resource, String> mapNames(Collection<Resource> roots) throws DatabaseException {
100         return Simantics.getSession().syncRequest((Read<Map<Resource, String>>) graph -> mapNames(graph, roots));
101     }
102
103     private Map<Resource, String> mapNames(ReadGraph graph, Collection<Resource> roots) throws DatabaseException {
104         Map<Resource, String> map = new HashMap<>();
105         for (Resource r : roots)
106             map.put(r, NameUtils.getSafeName(graph, r));
107         return map;
108     }
109
110 }