]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / migration / MigrationUtils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.layer0.migration;\r
13 \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
20 \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
58 \r
59 public class MigrationUtils {\r
60         \r
61         public static final boolean DEBUG = false;\r
62 \r
63     public static MigrationState newState() {\r
64         return new MigrationStateImpl();\r
65     }\r
66 \r
67     public static MigrationStep getStep(Session session, String uri) throws DatabaseException {\r
68         return session.sync(new UnaryRead<String, MigrationStep>(uri) {\r
69 \r
70             @Override\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
74             }\r
75 \r
76         });\r
77     }\r
78 \r
79 //    public static TransferableGraph1 getTG(Session session, MigrationState state) {\r
80 //        return getTG(session, state, true, false);\r
81 //    }\r
82     \r
83     public static void clearTempResource(Session session, final Resource resource) {\r
84         session.asyncRequest(new WriteRequest() {\r
85 \r
86             @Override\r
87             public void perform(WriteGraph graph) throws DatabaseException {\r
88                 graph.deny(resource, Layer0.getInstance(graph).PartOf);\r
89             }\r
90         });\r
91     }\r
92 \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
98                 \r
99                 @Override\r
100                 public void perform(WriteGraph graph) throws DatabaseException {\r
101                     \r
102                         Layer0 L0 = Layer0.getInstance(graph);\r
103                         \r
104                         for(Resource root : graph.getObjects(resource, L0.ConsistsOf)) {\r
105                                 \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
113                                         }\r
114                             } else {\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
118                             }\r
119                             }\r
120 \r
121                             graph.deny(root, L0.PartOf);\r
122                             graph.claim(root, L0.PartOf, parent);\r
123 \r
124                             CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
125                             graph.addMetadata(cm.add("Imported " + graph.getURI(root) + ", resource " + root));\r
126                             \r
127                             result.add(root);\r
128                     \r
129                         }\r
130                         \r
131                         graph.deny(resource, L0.PartOf);\r
132 \r
133                 }\r
134             });\r
135         } else {\r
136             TransferableGraph1 tg = getTG(session, state);\r
137             if(tg != null) {\r
138                 DefaultPasteHandler.defaultExecute(tg, parent, new IImportAdvisor() {\r
139                     \r
140                     @Override\r
141                     public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {\r
142                         Resource r = advisor.createRoot(graph, root);\r
143                         result.add(r);\r
144                         return r;\r
145                     }\r
146                     \r
147                     @Override\r
148                     public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {\r
149                         return advisor.analyzeRoot(graph, root);\r
150                     }\r
151                 });\r
152             }\r
153         }\r
154         return result;\r
155     }\r
156     \r
157     \r
158     @SuppressWarnings("deprecation")\r
159         public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {\r
160         \r
161         return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {\r
162 \r
163                         @Override\r
164                         public Collection<MigrationStep> perform(ReadGraph graph) throws DatabaseException {\r
165                                 \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
172                                 }\r
173                                 for(Resource migration : migrations) {\r
174                                         if(DEBUG)\r
175                                                 System.err.println("getMigrationSteps: " + graph.getURI(migration));\r
176                                         String format = graph.getRelatedValue(migration, L0.Migration_format);\r
177                                         if(DEBUG)\r
178                                                 System.err.println("-format=" + format);\r
179                                         if(parameter.equals(format)) {\r
180                                                 Integer from = graph.getRelatedValue(migration, L0.Migration_from);\r
181                                                 if(DEBUG)\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
187                                                         if(DEBUG)\r
188                                                                 System.err.println("=> ACCEPT");\r
189                                                 } else {\r
190                                                         if(DEBUG)\r
191                                                                 System.err.println("=> REJECT");\r
192                                                 }\r
193                                         }\r
194                                 }\r
195                                 /*\r
196                                 Resource base = graph.getResource(baseURI);\r
197                         if(DEBUG)\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
200                                 }*/\r
201                                 return CollectionUtils.sortByFirst(steps);\r
202                         }\r
203                 \r
204         });\r
205     }\r
206     \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
211         } else {\r
212             return null;\r
213         }\r
214     }\r
215 \r
216     public static Collection<Resource> importMigratedMany(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {\r
217 \r
218         //assert(target != null);\r
219         assert(advisor != null);\r
220         \r
221         if(monitor == null) monitor = new NullProgressMonitor();\r
222         \r
223         if(DEBUG)\r
224                 System.err.println("importMigrated: file=" + (modelFile != null ? modelFile.getAbsolutePath() : null));\r
225         \r
226         //String baseURI = state.getProperty(MigrationStateKeys.BASE_URI);\r
227 //      if(DEBUG)\r
228 //              System.err.println("importMigrated: baseURI=" + baseURI);\r
229 \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
234 \r
235         DataContainer dc = state.getProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER);\r
236         Collection<MigrationStep> migration = getMigrationSteps(dc);\r
237 \r
238 //        TransferableGraph1 tg = state.getProperty(MigrationStateKeys.CURRENT_TG);\r
239 //        state.setProperty(MigrationStateKeys.TG_EXTENSIONS, tg.extensions);\r
240         \r
241         for(MigrationStep step : migration) {\r
242             step.applyTo(monitor, session, state);\r
243             if (monitor.isCanceled())\r
244                 break;\r
245         }\r
246 \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
252                     @Override\r
253                     public void perform(WriteGraph graph) throws DatabaseException {\r
254                         new TrashBinRemover(root).remove(graph);\r
255                     }\r
256                 });\r
257             }\r
258             return Collections.emptyList();\r
259         }\r
260 \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
264                 return roots;\r
265         }\r
266                         \r
267         // Finally import model into final destination\r
268         return importTo(monitor, session, state, target, advisor);\r
269         \r
270     }\r
271     \r
272     public static TransferableGraph1 getTG(Session session, MigrationState state) throws DatabaseException {\r
273         return state.getProperty(MigrationStateKeys.CURRENT_TG);\r
274     }\r
275     \r
276     public static Resource getResource(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {\r
277         return state.getProperty(MigrationStateKeys.CURRENT_RESOURCE);\r
278     }\r
279 \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
282     }\r
283 \r
284     /**\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
287      * \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
296      */\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
300     }\r
301 \r
302     public static Resource importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {\r
303         return importSharedOntology(null, session, tg, published);\r
304     }\r
305 \r
306     public static Resource importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {\r
307         \r
308         if(monitor == null) monitor = new NullProgressMonitor();\r
309         \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
315 //                              @Override\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
321 //                              }\r
322 //              });\r
323             try {\r
324                 \r
325                 TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);\r
326                 SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);\r
327 //                TransferableGraphs.importGraph1(session, tgSource, advisor);\r
328                 \r
329 //                if (advisor.getRoots().size() == 1) {\r
330 //                      return advisor.getRoots().iterator().next();\r
331 //                }\r
332                                 //TransferableGraphs.importGraph1(session, tg, new SharedOntologyImportAdvisor(), null);\r
333 \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
341 \r
342                 return MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);\r
343                 \r
344                         } catch (TransferableGraphException e) {\r
345                                 throw new DatabaseException(e);\r
346                         } catch (MissingDependencyException e) {\r
347                                 throw e;\r
348                         } catch (Exception e) {\r
349                             throw new DatabaseException(e);\r
350             } finally {\r
351                 session.getService(XSupport.class).setServiceMode(false, false);\r
352             }\r
353             \r
354         }\r
355         \r
356         return null;\r
357         \r
358     }\r
359     \r
360 }\r