/******************************************************************************* * Copyright (c) 2019 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Semantum Oy - initial API and implementation *******************************************************************************/ package org.simantics.modeling.migration; import java.io.PrintWriter; import java.io.StringReader; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.simantics.Simantics; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.migration.MigrationState; import org.simantics.db.layer0.migration.MigrationStateKeys; import org.simantics.db.layer0.migration.MigrationStep; import org.simantics.db.layer0.migration.MigrationUtils; import org.simantics.db.layer0.migration.NullWriter; import org.simantics.db.request.Read; import org.simantics.modeling.ModelingResources; import org.simantics.scl.compiler.commands.CommandSession; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.osgi.SCLOsgi; import org.simantics.scl.runtime.reporting.AbstractSCLReportingHandler; import org.simantics.scl.runtime.reporting.SCLReportingHandler; /** * Runs the SCL script associated with the migration step. * * @author Tuukka Lehtonen * @since 1.41.0 */ public class SCLScriptMigrationStep implements MigrationStep { private String scriptId; private String script; public SCLScriptMigrationStep(ReadGraph graph, Resource step) throws DatabaseException { this.scriptId = NameUtils.getSafeName(graph, step); this.script = graph.getRelatedValue( step, ModelingResources.getInstance(graph).Migration_SCLScriptMigrationStep_script, Bindings.STRING); } @Override public void applyTo(final IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException { Collection roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES); if (!roots.isEmpty()) { PrintWriter log = MigrationUtils.getProperty(state, MigrationStateKeys.MESSAGE_LOG_WRITER, NullWriter.PRINT_INSTANCE); runScript(monitor, roots, log); } } private static class ReportingHandler extends AbstractSCLReportingHandler { PrintWriter log; public ReportingHandler(PrintWriter log) { this.log = log; } @Override public void print(String text) { log.println(text); } @Override public void printError(String error) { log.println("ERROR: " + error); } } private void runScript(IProgressMonitor monitor, Collection roots, PrintWriter log) throws DatabaseException { log.format("## Running SCL Script Migration Step `%s` ##%n", scriptId); SCLReportingHandler rh = new ReportingHandler(log); Map rootNames = mapNames(roots); for (Resource root : roots) { log.format("### Running script for root `%s` ###%n", rootNames.get(root)); CommandSession session = new CommandSession(SCLOsgi.MODULE_REPOSITORY, rh); session.setVariable("root", Types.RESOURCE, root); session.execute(new StringReader(script), rh); } } private Map mapNames(Collection roots) throws DatabaseException { return Simantics.getSession().syncRequest((Read>) graph -> mapNames(graph, roots)); } private Map mapNames(ReadGraph graph, Collection roots) throws DatabaseException { Map map = new HashMap<>(); for (Resource r : roots) map.put(r, NameUtils.getSafeName(graph, r)); return map; } }