]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationUtils.java
Make Write-interfaces as @FunctionalInterface for lambdas
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / migration / MigrationUtils.java
1 /*******************************************************************************
2  * Copyright (c) 2012 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  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.layer0.migration;
13
14 import java.io.File;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashSet;
19 import java.util.Set;
20
21 import org.eclipse.core.runtime.IProgressMonitor;
22 import org.eclipse.core.runtime.NullProgressMonitor;
23 import org.simantics.databoard.Bindings;
24 import org.simantics.databoard.binding.mutable.Variant;
25 import org.simantics.databoard.container.DataContainer;
26 import org.simantics.db.ReadGraph;
27 import org.simantics.db.Resource;
28 import org.simantics.db.Session;
29 import org.simantics.db.WriteGraph;
30 import org.simantics.db.WriteOnlyGraph;
31 import org.simantics.db.common.CommentMetadata;
32 import org.simantics.db.common.request.BinaryRead;
33 import org.simantics.db.common.request.FreshEscapedName;
34 import org.simantics.db.common.request.UnaryRead;
35 import org.simantics.db.common.request.WriteRequest;
36 import org.simantics.db.common.utils.VersionMap;
37 import org.simantics.db.common.utils.VersionMapRequest;
38 import org.simantics.db.common.utils.Versions;
39 import org.simantics.db.exception.DatabaseException;
40 import org.simantics.db.layer0.adapter.Instances;
41 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
42 import org.simantics.db.layer0.adapter.impl.SharedOntologyImportAdvisor;
43 import org.simantics.db.layer0.adapter.impl.TrashBinRemover;
44 import org.simantics.db.layer0.internal.SimanticsInternal;
45 import org.simantics.db.layer0.util.Layer0Utils;
46 import org.simantics.db.layer0.util.TGTransferableGraphSource;
47 import org.simantics.db.service.XSupport;
48 import org.simantics.graph.db.IImportAdvisor;
49 import org.simantics.graph.db.MissingDependencyException;
50 import org.simantics.graph.db.TransferableGraphException;
51 import org.simantics.graph.representation.Identity;
52 import org.simantics.graph.representation.Root;
53 import org.simantics.graph.representation.TransferableGraph1;
54 import org.simantics.graph.representation.TransferableGraphUtils;
55 import org.simantics.layer0.Layer0;
56 import org.simantics.utils.datastructures.Pair;
57 import org.simantics.utils.datastructures.collections.CollectionUtils;
58
59 public class MigrationUtils {
60         
61         public static final boolean DEBUG = false;
62
63     public static MigrationState newState() {
64         return new MigrationStateImpl();
65     }
66
67     public static MigrationStep getStep(Session session, String uri) throws DatabaseException {
68         return session.sync(new UnaryRead<String, MigrationStep>(uri) {
69
70             @Override
71             public MigrationStep perform(ReadGraph graph) throws DatabaseException {
72                 Resource r = graph.getResource(parameter);
73                 return graph.adapt(r, MigrationStep.class);
74             }
75
76         });
77     }
78
79 //    public static TransferableGraph1 getTG(Session session, MigrationState state) {
80 //        return getTG(session, state, true, false);
81 //    }
82     
83     public static void clearTempResource(Session session, final Resource resource) {
84         session.asyncRequest(new WriteRequest() {
85
86             @Override
87             public void perform(WriteGraph graph) throws DatabaseException {
88                 graph.deny(resource, Layer0.getInstance(graph).PartOf);
89             }
90         });
91     }
92
93     public static Collection<Resource> importTo(IProgressMonitor monitor, Session session, MigrationState state, final Resource parent, final IImportAdvisor advisor) throws DatabaseException, TransferableGraphException {
94         final Resource resource = getResource(monitor, session, state);
95         final ArrayList<Resource> result = new ArrayList<Resource>();
96         if(resource != null) {
97             session.syncRequest(new WriteRequest() {
98                 
99                 @Override
100                 public void perform(WriteGraph graph) throws DatabaseException {
101                     
102                         Layer0 L0 = Layer0.getInstance(graph);
103                         
104                         for(Resource root : graph.getObjects(resource, L0.ConsistsOf)) {
105                                 
106                                 String baseName = Versions.getBaseName(graph, root);
107                             String version = Versions.getVersion(graph, root);
108                             if(version != null) {
109                                         VersionMap map = graph.syncRequest(new VersionMapRequest(parent));
110                                         if(map.contains(baseName, version)) {
111                                     String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
112                                         graph.claimLiteral(root, L0.HasName, newName + "@1", Bindings.STRING);
113                                         }
114                             } else {
115                             String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
116                             if(!newName.equals(baseName)) {
117                                 graph.claimLiteral(root, L0.HasName, newName, Bindings.STRING);
118                             }
119                             }
120
121                             graph.deny(root, L0.PartOf);
122                             graph.claim(root, L0.PartOf, parent);
123
124                             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
125                             graph.addMetadata(cm.add("Imported " + graph.getURI(root) + ", resource " + root));
126                             
127                             result.add(root);
128                     
129                         }
130                         
131                         graph.deny(resource, L0.PartOf);
132
133                 }
134             });
135         } else {
136             TransferableGraph1 tg = getTG(session, state);
137             if(tg != null) {
138                 DefaultPasteHandler.defaultExecute(tg, parent, new IImportAdvisor() {
139                     
140                     @Override
141                     public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {
142                         Resource r = advisor.createRoot(graph, root);
143                         result.add(r);
144                         return r;
145                     }
146                     
147                     @Override
148                     public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
149                         return advisor.analyzeRoot(graph, root);
150                     }
151                 });
152             }
153         }
154         return result;
155     }
156     
157     
158     @SuppressWarnings("deprecation")
159         public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {
160         
161         return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {
162
163                         @Override
164                         public Collection<MigrationStep> perform(ReadGraph graph) throws DatabaseException {
165                                 
166                                 Layer0 L0 = Layer0.getInstance(graph);
167                                 ArrayList<Pair<Double,MigrationStep>> steps = new ArrayList<Pair<Double,MigrationStep>>();
168                         Instances query = graph.adapt(L0.Migration, Instances.class);
169                         Set<Resource> migrations = new HashSet<Resource>();
170                                 for(Resource ontology : Layer0Utils.listOntologies(graph)) {
171                                         migrations.addAll(Layer0Utils.sortByCluster(graph, query.find(graph, ontology)));
172                                 }
173                                 for(Resource migration : migrations) {
174                                         if(DEBUG)
175                                                 System.err.println("getMigrationSteps: " + graph.getURI(migration));
176                                         String format = graph.getRelatedValue(migration, L0.Migration_format);
177                                         if(DEBUG)
178                                                 System.err.println("-format=" + format);
179                                         if(parameter.equals(format)) {
180                                                 Integer from = graph.getRelatedValue(migration, L0.Migration_from);
181                                                 if(DEBUG)
182                                                         System.err.println("-from=" + from);
183                                                 Resource step = graph.getSingleObject(migration, L0.Migration_step);
184                                                 if(parameter2.equals(from)) {
185                                                         Double priority = graph.getRelatedValue(migration, L0.Migration_priority);
186                                                         steps.add(Pair.make(-priority, graph.adapt(step, MigrationStep.class))); 
187                                                         if(DEBUG)
188                                                                 System.err.println("=> ACCEPT");
189                                                 } else {
190                                                         if(DEBUG)
191                                                                 System.err.println("=> REJECT");
192                                                 }
193                                         }
194                                 }
195                                 /*
196                                 Resource base = graph.getResource(baseURI);
197                         if(DEBUG)
198                                 System.err.println("getMigrationSteps format=" + parameter + ", version=" + parameter2);
199                                 for(Resource migration : graph.sync(new ObjectsWithType(base, L0.ConsistsOf, L0.Migration))) {
200                                 }*/
201                                 return CollectionUtils.sortByFirst(steps);
202                         }
203                 
204         });
205     }
206     
207     public static Resource importMigrated(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
208         Collection<Resource> roots = importMigratedMany(monitor, session, modelFile, state, advisor, target);
209         if(roots.size() == 1) {
210             return roots.iterator().next();
211         } else {
212             return null;
213         }
214     }
215
216     public static Collection<Resource> importMigratedMany(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
217
218         //assert(target != null);
219         assert(advisor != null);
220         
221         if(monitor == null) monitor = new NullProgressMonitor();
222         
223         if(DEBUG)
224                 System.err.println("importMigrated: file=" + (modelFile != null ? modelFile.getAbsolutePath() : null));
225         
226         //String baseURI = state.getProperty(MigrationStateKeys.BASE_URI);
227 //      if(DEBUG)
228 //              System.err.println("importMigrated: baseURI=" + baseURI);
229
230         state.setProperty(MigrationStateKeys.MODEL_FILE, modelFile);
231         state.setProperty(MigrationStateKeys.SESSION, session);
232         state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
233         state.setProperty(MigrationStateKeys.IMPORT_ADVISOR, advisor);
234
235         DataContainer dc = state.getProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER);
236         Collection<MigrationStep> migration = getMigrationSteps(dc);
237
238 //        TransferableGraph1 tg = state.getProperty(MigrationStateKeys.CURRENT_TG);
239 //        state.setProperty(MigrationStateKeys.TG_EXTENSIONS, tg.extensions);
240         
241         for(MigrationStep step : migration) {
242             step.applyTo(monitor, session, state);
243             if (monitor.isCanceled())
244                 break;
245         }
246
247         if (monitor.isCanceled()) {
248             // Move possibly created material into TrashBin and quit.
249             final Resource root = state.probeProperty(MigrationStateKeys.CURRENT_RESOURCE);
250             if (root != null) {
251                 session.syncRequest(new WriteRequest() {
252                     @Override
253                     public void perform(WriteGraph graph) throws DatabaseException {
254                         new TrashBinRemover(root).remove(graph);
255                     }
256                 });
257             }
258             return Collections.emptyList();
259         }
260
261         // Absolute path imports end up here
262         if(target == null) {
263                 Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
264                 return roots;
265         }
266                         
267         // Finally import model into final destination
268         return importTo(monitor, session, state, target, advisor);
269         
270     }
271     
272     public static TransferableGraph1 getTG(Session session, MigrationState state) throws DatabaseException {
273         return state.getProperty(MigrationStateKeys.CURRENT_TG);
274     }
275     
276     public static Resource getResource(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
277         return state.getProperty(MigrationStateKeys.CURRENT_RESOURCE);
278     }
279
280     public static Collection<Resource> getRootResources(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
281         return state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
282     }
283
284     /**
285      * Get a property from the specified MigrationState and return specified
286      * default value if the property value is <code>null</code>.
287      * 
288      * @param state the state to get the property from
289      * @param key the property to get
290      * @param defaultValue
291      *            the default value to return if the property value is
292      *            <code>null</code>
293      * @return the property value
294      * @throws DatabaseException
295      *             if fetching the property fails for some reason
296      */
297     public static <T> T getProperty(MigrationState state, String key, T defaultValue) throws DatabaseException {
298         T t = state.getProperty(key);
299         return t != null ? t : defaultValue;
300     }
301
302     public static Resource importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
303         return importSharedOntology(null, session, tg, published);
304     }
305
306     public static Resource importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
307         
308         if(monitor == null) monitor = new NullProgressMonitor();
309         
310         Collection<Identity> roots = TransferableGraphUtils.getRoots(tg);
311         if(roots.size() == 1) {
312 //              Identity id = roots.iterator().next();
313 //              final Root root = (Root)id.definition;
314 //              Resource rootResource = session.syncRequest(new WriteResultRequest<Resource>() {
315 //                              @Override
316 //                              public Resource perform(WriteGraph graph) throws DatabaseException {
317 //                                      Resource type = graph.getResource(root.type);
318 //                                      Resource existing = graph.getPossibleResource(root.name);
319 //                                      if(existing != null) throw new DatabaseException("Shared library " + root.name + " exists already.");
320 //                                      return Layer0Utils.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, root.name, type);
321 //                              }
322 //              });
323             try {
324                 
325                 TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);
326                 SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);
327 //                TransferableGraphs.importGraph1(session, tgSource, advisor);
328                 
329 //                if (advisor.getRoots().size() == 1) {
330 //                      return advisor.getRoots().iterator().next();
331 //                }
332                                 //TransferableGraphs.importGraph1(session, tg, new SharedOntologyImportAdvisor(), null);
333
334                 MigrationState state = newState();
335                 //state.setProperty(MigrationStateKeys.BASE_URI, AprosBuiltins.URIs.Migration);
336                 state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, false);
337                 state.setProperty(MigrationStateKeys.CURRENT_TGS, tgSource);
338                 state.setProperty(MigrationStateKeys.SESSION, session);
339                 state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
340                 state.setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, new DataContainer("sharedLibrary", 1, new Variant(TransferableGraph1.BINDING, tg)));
341
342                 return MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);
343                 
344                         } catch (TransferableGraphException e) {
345                                 throw new DatabaseException(e);
346                         } catch (MissingDependencyException e) {
347                                 throw e;
348                         } catch (DatabaseException e) {
349                                 throw e;
350                         } catch (Exception e) {
351                             throw new DatabaseException(e);
352             } finally {
353                 session.getService(XSupport.class).setServiceMode(false, false);
354             }
355             
356         }
357         
358         return null;
359         
360     }
361     
362 }