1 package org.simantics.db.layer0.migration;
3 import java.io.PrintWriter;
4 import java.util.ArrayList;
5 import java.util.Collection;
8 import org.eclipse.core.runtime.IProgressMonitor;
9 import org.simantics.databoard.Bindings;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.RequestProcessor;
12 import org.simantics.db.Resource;
13 import org.simantics.db.Session;
14 import org.simantics.db.WriteGraph;
15 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
16 import org.simantics.db.common.request.DelayedWriteRequest;
17 import org.simantics.db.common.utils.ListUtils;
18 import org.simantics.db.common.utils.NameUtils;
19 import org.simantics.db.exception.DatabaseException;
20 import org.simantics.db.layer0.adapter.impl.EntityInstances.QueryIndex;
21 import org.simantics.db.layer0.request.PossibleResource;
22 import org.simantics.layer0.Layer0;
25 * Changes L0.InstanceOf relations according to descriptions in the migrated
28 * @author Tuukka Lehtonen
31 public class InstanceOfMigrationStep implements MigrationStep {
33 private static class Migration {
34 public final String fromUri;
35 public final String toUri;
37 public Migration(String from, String to) {
43 public String toString() {
44 return fromUri + " -> " + toUri;
48 private static class RMigration {
49 public final Migration m;
50 public final Resource from;
51 public final Resource to;
53 public RMigration(RequestProcessor processor, Migration m) throws DatabaseException {
55 this.from = processor.syncRequest(new PossibleResource(m.fromUri));
56 this.to = processor.syncRequest(new PossibleResource(m.toUri));
59 public boolean isValid() {
60 return from != null && to != null;
64 private final Migration[] migrations;
66 public InstanceOfMigrationStep(String fromUri, String toUri) {
67 this.migrations = new Migration[] { new Migration(fromUri, toUri) };
70 public InstanceOfMigrationStep(ReadGraph graph, Resource step) throws DatabaseException {
71 List<Migration> ms = new ArrayList<>();
72 List<Resource> uris = ListUtils.toList(graph, step);
73 int size = uris.size() & ~1;
74 for (int i = 0; i < size; i += 2) {
75 String from = graph.getPossibleValue(uris.get(i), Bindings.STRING);
76 String to = graph.getPossibleValue(uris.get(i+1), Bindings.STRING);
77 if (from != null && to != null)
78 ms.add(new Migration(from, to));
80 migrations = ms.toArray(new Migration[ms.size()]);
84 public void applyTo(final IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
85 final Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
88 final PrintWriter log = MigrationUtils.getProperty(state, MigrationStateKeys.MESSAGE_LOG_WRITER, NullWriter.PRINT_INSTANCE);
90 session.sync(new DelayedWriteRequest() {
92 public void perform(WriteGraph graph) throws DatabaseException {
93 migrateInstances(monitor, graph, roots, log);
98 private void migrateInstances(IProgressMonitor monitor, WriteGraph graph, Collection<Resource> roots, PrintWriter log) throws DatabaseException {
99 for (Migration m : migrations)
100 migrateInstances(monitor, graph, new RMigration(graph, m), roots, log);
103 private void migrateInstances(IProgressMonitor monitor, WriteGraph graph, RMigration rm, Collection<Resource> roots, PrintWriter log) throws DatabaseException {
104 log.println("## InstanceOf Migration ##");
105 log.println("* From: `" + rm.m.fromUri + "`");
106 log.println("* To: `" + rm.m.toUri + "`");
108 for (Resource root : roots)
109 migrateInstances(monitor, graph, root, rm, log);
111 log.println("\nSkipping migration as invalid.\n");
115 private static void migrateInstances(IProgressMonitor monitor, WriteGraph graph, Resource root, RMigration migration, PrintWriter log) throws DatabaseException {
116 log.println("### Migrating root `" + NameUtils.getSafeName(graph, root) + "` ###");
117 String rootUri = NameUtils.getURIOrSafeNameInternal(graph, root);
118 Layer0 L0 = Layer0.getInstance(graph);
120 for (Resource instance : instancesOf(graph, root, migration.from)) {
121 if (graph.hasStatement(instance, L0.InstanceOf, migration.from)) {
122 graph.deny(instance, L0.InstanceOf, null, migration.from);
123 graph.claim(instance, L0.InstanceOf, null, migration.to);
124 log.println("* `" + relativeUri(graph, rootUri, instance) + "`");
129 private static List<Resource> instancesOf(ReadGraph graph, Resource root, Resource type) throws DatabaseException {
130 return graph.syncRequest(
131 new QueryIndex(root, type, ""),
132 TransientCacheListener.<List<Resource>>instance());
135 private static String relativeUri(ReadGraph graph, String rootUri, Resource r) throws DatabaseException {
136 String uri = graph.getPossibleURI(r);
138 ? uri.substring(rootUri.length())
139 : NameUtils.getURIOrSafeNameInternal(graph, r);