1 /*******************************************************************************
\r
2 * Copyright (c) 2012 Association for Decentralized Information Management in
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.layer0.migration;
\r
14 import java.io.File;
\r
15 import java.util.ArrayList;
\r
16 import java.util.Collection;
\r
17 import java.util.Collections;
\r
18 import java.util.HashSet;
\r
19 import java.util.Set;
\r
21 import org.eclipse.core.runtime.IProgressMonitor;
\r
22 import org.eclipse.core.runtime.NullProgressMonitor;
\r
23 import org.simantics.databoard.Bindings;
\r
24 import org.simantics.databoard.binding.mutable.Variant;
\r
25 import org.simantics.databoard.container.DataContainer;
\r
26 import org.simantics.db.ReadGraph;
\r
27 import org.simantics.db.Resource;
\r
28 import org.simantics.db.Session;
\r
29 import org.simantics.db.WriteGraph;
\r
30 import org.simantics.db.WriteOnlyGraph;
\r
31 import org.simantics.db.common.CommentMetadata;
\r
32 import org.simantics.db.common.request.BinaryRead;
\r
33 import org.simantics.db.common.request.FreshEscapedName;
\r
34 import org.simantics.db.common.request.UnaryRead;
\r
35 import org.simantics.db.common.request.WriteRequest;
\r
36 import org.simantics.db.common.utils.VersionMap;
\r
37 import org.simantics.db.common.utils.VersionMapRequest;
\r
38 import org.simantics.db.common.utils.Versions;
\r
39 import org.simantics.db.exception.DatabaseException;
\r
40 import org.simantics.db.layer0.adapter.Instances;
\r
41 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
\r
42 import org.simantics.db.layer0.adapter.impl.SharedOntologyImportAdvisor;
\r
43 import org.simantics.db.layer0.adapter.impl.TrashBinRemover;
\r
44 import org.simantics.db.layer0.internal.SimanticsInternal;
\r
45 import org.simantics.db.layer0.util.Layer0Utils;
\r
46 import org.simantics.db.layer0.util.TGTransferableGraphSource;
\r
47 import org.simantics.db.service.XSupport;
\r
48 import org.simantics.graph.db.IImportAdvisor;
\r
49 import org.simantics.graph.db.MissingDependencyException;
\r
50 import org.simantics.graph.db.TransferableGraphException;
\r
51 import org.simantics.graph.representation.Identity;
\r
52 import org.simantics.graph.representation.Root;
\r
53 import org.simantics.graph.representation.TransferableGraph1;
\r
54 import org.simantics.graph.representation.TransferableGraphUtils;
\r
55 import org.simantics.layer0.Layer0;
\r
56 import org.simantics.utils.datastructures.Pair;
\r
57 import org.simantics.utils.datastructures.collections.CollectionUtils;
\r
59 public class MigrationUtils {
\r
61 public static final boolean DEBUG = false;
\r
63 public static MigrationState newState() {
\r
64 return new MigrationStateImpl();
\r
67 public static MigrationStep getStep(Session session, String uri) throws DatabaseException {
\r
68 return session.sync(new UnaryRead<String, MigrationStep>(uri) {
\r
71 public MigrationStep perform(ReadGraph graph) throws DatabaseException {
\r
72 Resource r = graph.getResource(parameter);
\r
73 return graph.adapt(r, MigrationStep.class);
\r
79 // public static TransferableGraph1 getTG(Session session, MigrationState state) {
\r
80 // return getTG(session, state, true, false);
\r
83 public static void clearTempResource(Session session, final Resource resource) {
\r
84 session.asyncRequest(new WriteRequest() {
\r
87 public void perform(WriteGraph graph) throws DatabaseException {
\r
88 graph.deny(resource, Layer0.getInstance(graph).PartOf);
\r
93 public static Collection<Resource> importTo(IProgressMonitor monitor, Session session, MigrationState state, final Resource parent, final IImportAdvisor advisor) throws DatabaseException, TransferableGraphException {
\r
94 final Resource resource = getResource(monitor, session, state);
\r
95 final ArrayList<Resource> result = new ArrayList<Resource>();
\r
96 if(resource != null) {
\r
97 session.syncRequest(new WriteRequest() {
\r
100 public void perform(WriteGraph graph) throws DatabaseException {
\r
102 Layer0 L0 = Layer0.getInstance(graph);
\r
104 for(Resource root : graph.getObjects(resource, L0.ConsistsOf)) {
\r
106 String baseName = Versions.getBaseName(graph, root);
\r
107 String version = Versions.getVersion(graph, root);
\r
108 if(version != null) {
\r
109 VersionMap map = graph.syncRequest(new VersionMapRequest(parent));
\r
110 if(map.contains(baseName, version)) {
\r
111 String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
\r
112 graph.claimLiteral(root, L0.HasName, newName + "@1", Bindings.STRING);
\r
115 String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
\r
116 if(!newName.equals(baseName)) {
\r
117 graph.claimLiteral(root, L0.HasName, newName, Bindings.STRING);
\r
121 graph.deny(root, L0.PartOf);
\r
122 graph.claim(root, L0.PartOf, parent);
\r
124 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
\r
125 graph.addMetadata(cm.add("Imported " + graph.getURI(root) + ", resource " + root));
\r
131 graph.deny(resource, L0.PartOf);
\r
136 TransferableGraph1 tg = getTG(session, state);
\r
138 DefaultPasteHandler.defaultExecute(tg, parent, new IImportAdvisor() {
\r
141 public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {
\r
142 Resource r = advisor.createRoot(graph, root);
\r
148 public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
\r
149 return advisor.analyzeRoot(graph, root);
\r
158 @SuppressWarnings("deprecation")
\r
159 public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {
\r
161 return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {
\r
164 public Collection<MigrationStep> perform(ReadGraph graph) throws DatabaseException {
\r
166 Layer0 L0 = Layer0.getInstance(graph);
\r
167 ArrayList<Pair<Double,MigrationStep>> steps = new ArrayList<Pair<Double,MigrationStep>>();
\r
168 Instances query = graph.adapt(L0.Migration, Instances.class);
\r
169 Set<Resource> migrations = new HashSet<Resource>();
\r
170 for(Resource ontology : Layer0Utils.listOntologies(graph)) {
\r
171 migrations.addAll(Layer0Utils.sortByCluster(graph, query.find(graph, ontology)));
\r
173 for(Resource migration : migrations) {
\r
175 System.err.println("getMigrationSteps: " + graph.getURI(migration));
\r
176 String format = graph.getRelatedValue(migration, L0.Migration_format);
\r
178 System.err.println("-format=" + format);
\r
179 if(parameter.equals(format)) {
\r
180 Integer from = graph.getRelatedValue(migration, L0.Migration_from);
\r
182 System.err.println("-from=" + from);
\r
183 Resource step = graph.getSingleObject(migration, L0.Migration_step);
\r
184 if(parameter2.equals(from)) {
\r
185 Double priority = graph.getRelatedValue(migration, L0.Migration_priority);
\r
186 steps.add(Pair.make(-priority, graph.adapt(step, MigrationStep.class)));
\r
188 System.err.println("=> ACCEPT");
\r
191 System.err.println("=> REJECT");
\r
196 Resource base = graph.getResource(baseURI);
\r
198 System.err.println("getMigrationSteps format=" + parameter + ", version=" + parameter2);
\r
199 for(Resource migration : graph.sync(new ObjectsWithType(base, L0.ConsistsOf, L0.Migration))) {
\r
201 return CollectionUtils.sortByFirst(steps);
\r
207 public static Resource importMigrated(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
\r
208 Collection<Resource> roots = importMigratedMany(monitor, session, modelFile, state, advisor, target);
\r
209 if(roots.size() == 1) {
\r
210 return roots.iterator().next();
\r
216 public static Collection<Resource> importMigratedMany(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
\r
218 //assert(target != null);
\r
219 assert(advisor != null);
\r
221 if(monitor == null) monitor = new NullProgressMonitor();
\r
224 System.err.println("importMigrated: file=" + (modelFile != null ? modelFile.getAbsolutePath() : null));
\r
226 //String baseURI = state.getProperty(MigrationStateKeys.BASE_URI);
\r
228 // System.err.println("importMigrated: baseURI=" + baseURI);
\r
230 state.setProperty(MigrationStateKeys.MODEL_FILE, modelFile);
\r
231 state.setProperty(MigrationStateKeys.SESSION, session);
\r
232 state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
\r
233 state.setProperty(MigrationStateKeys.IMPORT_ADVISOR, advisor);
\r
235 DataContainer dc = state.getProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER);
\r
236 Collection<MigrationStep> migration = getMigrationSteps(dc);
\r
238 // TransferableGraph1 tg = state.getProperty(MigrationStateKeys.CURRENT_TG);
\r
239 // state.setProperty(MigrationStateKeys.TG_EXTENSIONS, tg.extensions);
\r
241 for(MigrationStep step : migration) {
\r
242 step.applyTo(monitor, session, state);
\r
243 if (monitor.isCanceled())
\r
247 if (monitor.isCanceled()) {
\r
248 // Move possibly created material into TrashBin and quit.
\r
249 final Resource root = state.probeProperty(MigrationStateKeys.CURRENT_RESOURCE);
\r
250 if (root != null) {
\r
251 session.syncRequest(new WriteRequest() {
\r
253 public void perform(WriteGraph graph) throws DatabaseException {
\r
254 new TrashBinRemover(root).remove(graph);
\r
258 return Collections.emptyList();
\r
261 // Absolute path imports end up here
\r
262 if(target == null) {
\r
263 Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
\r
267 // Finally import model into final destination
\r
268 return importTo(monitor, session, state, target, advisor);
\r
272 public static TransferableGraph1 getTG(Session session, MigrationState state) throws DatabaseException {
\r
273 return state.getProperty(MigrationStateKeys.CURRENT_TG);
\r
276 public static Resource getResource(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
\r
277 return state.getProperty(MigrationStateKeys.CURRENT_RESOURCE);
\r
280 public static Collection<Resource> getRootResources(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
\r
281 return state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
\r
285 * Get a property from the specified MigrationState and return specified
\r
286 * default value if the property value is <code>null</code>.
\r
288 * @param state the state to get the property from
\r
289 * @param key the property to get
\r
290 * @param defaultValue
\r
291 * the default value to return if the property value is
\r
292 * <code>null</code>
\r
293 * @return the property value
\r
294 * @throws DatabaseException
\r
295 * if fetching the property fails for some reason
\r
297 public static <T> T getProperty(MigrationState state, String key, T defaultValue) throws DatabaseException {
\r
298 T t = state.getProperty(key);
\r
299 return t != null ? t : defaultValue;
\r
302 public static Resource importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
\r
303 return importSharedOntology(null, session, tg, published);
\r
306 public static Resource importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
\r
308 if(monitor == null) monitor = new NullProgressMonitor();
\r
310 Collection<Identity> roots = TransferableGraphUtils.getRoots(tg);
\r
311 if(roots.size() == 1) {
\r
312 // Identity id = roots.iterator().next();
\r
313 // final Root root = (Root)id.definition;
\r
314 // Resource rootResource = session.syncRequest(new WriteResultRequest<Resource>() {
\r
316 // public Resource perform(WriteGraph graph) throws DatabaseException {
\r
317 // Resource type = graph.getResource(root.type);
\r
318 // Resource existing = graph.getPossibleResource(root.name);
\r
319 // if(existing != null) throw new DatabaseException("Shared library " + root.name + " exists already.");
\r
320 // return Layer0Utils.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, root.name, type);
\r
325 TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);
\r
326 SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);
\r
327 // TransferableGraphs.importGraph1(session, tgSource, advisor);
\r
329 // if (advisor.getRoots().size() == 1) {
\r
330 // return advisor.getRoots().iterator().next();
\r
332 //TransferableGraphs.importGraph1(session, tg, new SharedOntologyImportAdvisor(), null);
\r
334 MigrationState state = newState();
\r
335 //state.setProperty(MigrationStateKeys.BASE_URI, AprosBuiltins.URIs.Migration);
\r
336 state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, false);
\r
337 state.setProperty(MigrationStateKeys.CURRENT_TGS, tgSource);
\r
338 state.setProperty(MigrationStateKeys.SESSION, session);
\r
339 state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
\r
340 state.setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, new DataContainer("sharedLibrary", 1, new Variant(TransferableGraph1.BINDING, tg)));
\r
342 return MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);
\r
344 } catch (TransferableGraphException e) {
\r
345 throw new DatabaseException(e);
\r
346 } catch (MissingDependencyException e) {
\r
348 } catch (Exception e) {
\r
349 throw new DatabaseException(e);
\r
351 session.getService(XSupport.class).setServiceMode(false, false);
\r