]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / migration / MigrationStateImpl.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.io.IOException;\r
16 import java.text.DateFormat;\r
17 import java.util.ArrayList;\r
18 import java.util.Collection;\r
19 import java.util.Date;\r
20 import java.util.HashMap;\r
21 import java.util.Map;\r
22 \r
23 import org.eclipse.core.runtime.IProgressMonitor;\r
24 import org.simantics.databoard.Bindings;\r
25 import org.simantics.databoard.binding.mutable.Variant;\r
26 import org.simantics.databoard.container.DataContainer;\r
27 import org.simantics.db.ReadGraph;\r
28 import org.simantics.db.Resource;\r
29 import org.simantics.db.Session;\r
30 import org.simantics.db.WriteGraph;\r
31 import org.simantics.db.WriteOnlyGraph;\r
32 import org.simantics.db.common.request.WriteResultRequest;\r
33 import org.simantics.db.common.utils.Logger;\r
34 import org.simantics.db.exception.AssumptionException;\r
35 import org.simantics.db.exception.DatabaseException;\r
36 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
37 import org.simantics.db.layer0.internal.SimanticsInternal;\r
38 import org.simantics.db.layer0.util.Layer0Utils;\r
39 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
40 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
41 import org.simantics.db.request.Read;\r
42 import org.simantics.db.service.ManagementSupport;\r
43 import org.simantics.db.service.SerialisationSupport;\r
44 import org.simantics.graph.db.IImportAdvisor;\r
45 import org.simantics.graph.db.IImportAdvisor2;\r
46 import org.simantics.graph.db.StreamingTransferableGraphFileReader;\r
47 import org.simantics.graph.db.TGStatusMonitor;\r
48 import org.simantics.graph.db.TransferableGraphImporter;\r
49 import org.simantics.graph.db.TransferableGraphSource;\r
50 import org.simantics.graph.db.TransferableGraphs;\r
51 import org.simantics.graph.db.WrapperAdvisor;\r
52 import org.simantics.graph.representation.ByteFileReader;\r
53 import org.simantics.graph.representation.TransferableGraph1;\r
54 import org.simantics.graph.representation.TransferableGraphFileReader;\r
55 import org.simantics.layer0.Layer0;\r
56 \r
57 public class MigrationStateImpl implements MigrationState {\r
58 \r
59         final private HashMap<String, Object> properties = new HashMap<String, Object>();\r
60         \r
61     @SuppressWarnings("unchecked")\r
62     @Override\r
63     public <T> T probeProperty(String key) throws DatabaseException {\r
64         return (T)properties.get(key);\r
65     }\r
66 \r
67         @SuppressWarnings("unchecked")\r
68     @Override\r
69         public <T> T getProperty(String key) throws DatabaseException {\r
70             \r
71             T property = (T)properties.get(key);\r
72             if(property != null) return property;\r
73             \r
74             if(MigrationStateKeys.BASE_URI.equals(key)) {\r
75                 throw new IllegalStateException("Base URI needs to be supplied for migration.");\r
76         } else if (MigrationStateKeys.SESSION.equals(key)) {\r
77             throw new IllegalStateException("Session needs to be supplied for migration.");\r
78         } else if (MigrationStateKeys.MODEL_FILE.equals(key)) {\r
79             throw new IllegalStateException("Model file needs to be supplied for migration.");\r
80             } else if (MigrationStateKeys.CURRENT_TG.equals(key)) {\r
81                 \r
82                 final Resource resource = probeProperty(MigrationStateKeys.CURRENT_RESOURCE);\r
83                 final Collection<Resource> roots = probeProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);\r
84                 if(roots != null) {\r
85                     Session session = getProperty(MigrationStateKeys.SESSION);\r
86                     TransferableGraph1 tg = session.syncRequest(new Read<TransferableGraph1>() {\r
87                         @Override\r
88                         public TransferableGraph1 perform(ReadGraph graph) throws DatabaseException {\r
89                             TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, roots, true, false);\r
90                             TransferableGraphSource source = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
91                             return TransferableGraphs.create(graph, source);\r
92                         }\r
93                     });\r
94                     if (resource != null)\r
95                         MigrationUtils.clearTempResource(session, resource);\r
96                     setProperty(MigrationStateKeys.CURRENT_RESOURCE, null);\r
97                     setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, null);\r
98                 setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, null);\r
99                     setProperty(MigrationStateKeys.CURRENT_TG, tg);\r
100                     return (T)tg;\r
101                 }\r
102                 \r
103             TransferableGraphFileReader reader = null;\r
104             try {\r
105                 File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);\r
106                 reader = new TransferableGraphFileReader(modelFile);\r
107                 TransferableGraph1 tg = reader.readTG();\r
108                 setProperty(MigrationStateKeys.CURRENT_TG, tg);\r
109                 return (T)tg;\r
110             } catch (DatabaseException e) {\r
111                 throw e;\r
112             } catch (Throwable t) {\r
113                 throw new DatabaseException(t);\r
114             } finally {\r
115                 uncheckedClose(reader);\r
116             }\r
117                 \r
118         } else if (MigrationStateKeys.CURRENT_TGS.equals(key)) {\r
119 \r
120             File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);\r
121             \r
122             try {\r
123                 StreamingTransferableGraphFileReader reader = new StreamingTransferableGraphFileReader(modelFile);\r
124                 TransferableGraphSource tgs = reader.readTG();\r
125                 setProperty(MigrationStateKeys.CURRENT_TGS_READER, reader);\r
126                 setProperty(MigrationStateKeys.CURRENT_TGS, tgs);\r
127                 return (T)tgs;\r
128             } catch (DatabaseException e) {\r
129                 throw e;\r
130             } catch (IOException e) {\r
131                 throw new DatabaseException("An I/O exception occurred during reading '" + modelFile.getAbsolutePath() + "'", e);\r
132             } catch (Throwable t) {\r
133                 throw new DatabaseException(t);\r
134             }\r
135 \r
136         } else if (MigrationStateKeys.CURRENT_DATA_CONTAINER.equals(key)) {\r
137             \r
138             try {\r
139                 \r
140                 TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS);\r
141                 DataContainer dc = tgs.getHeader();\r
142                 setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, dc);\r
143                 return (T)dc;\r
144                 \r
145             } catch (DatabaseException e) {\r
146                 throw e;\r
147             } catch (Throwable t) {\r
148                 throw new DatabaseException(t);\r
149             }\r
150             \r
151         } else if (MigrationStateKeys.TG_EXTENSIONS.equals(key)) {\r
152             \r
153             try {\r
154                 \r
155                 TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS);\r
156                 Map<String,Variant> extensions = tgs.getExtensions();\r
157                 setProperty(MigrationStateKeys.TG_EXTENSIONS, extensions);\r
158                 return (T)extensions;\r
159                 \r
160             } catch (DatabaseException e) {\r
161                 throw e;\r
162             } catch (Throwable t) {\r
163                 throw new DatabaseException(t);\r
164             }\r
165 \r
166         } else if (MigrationStateKeys.CURRENT_RESOURCE.equals(key) || MigrationStateKeys.CURRENT_ROOT_RESOURCES.equals(key)) {\r
167             \r
168             final Session session = getProperty(MigrationStateKeys.SESSION);\r
169             final IProgressMonitor monitor = probeProperty(MigrationStateKeys.PROGRESS_MONITOR);\r
170             final boolean updateDependencies = MigrationUtils.getProperty(this, MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.TRUE);\r
171             \r
172             final TransferableGraph1 tg = probeProperty(MigrationStateKeys.CURRENT_TG);\r
173             if(tg != null) {\r
174                 \r
175                 final Resource indexRoot = session.syncRequest(new WriteResultRequest<Resource>() {\r
176                     @Override\r
177                     public Resource perform(WriteGraph graph) throws DatabaseException {\r
178                         if(!updateDependencies)\r
179                             Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
180                         return createTemporaryRoot(graph);\r
181                     }\r
182                 });\r
183 \r
184                 IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot));\r
185                 IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) {\r
186                         @Override\r
187                     public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {\r
188                         super.beforeWrite(graph, process);\r
189                         if(!updateDependencies)\r
190                             Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
191                     }\r
192                         @Override\r
193                     public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {\r
194                         super.afterWrite(graph, process);\r
195                         Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS);\r
196                         if(storeResources != null && storeResources) {\r
197                                 long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class));\r
198                                 setProperty(MigrationStateKeys.RESOURCE_IDS, ids);\r
199                         }\r
200                     }\r
201                                 };\r
202                                 // Make sure that the supplied advisor is redirected to temp\r
203                                 advisor.redirect(indexRoot);\r
204                 \r
205                 TransferableGraphs.importGraph1WithMonitor(session, tg, advisor, new TGStatusMonitor() {\r
206                     @Override\r
207                     public void status(int percentage) {\r
208                         monitor.subTask("Importing model from file (" + percentage + "%)");\r
209                     }\r
210                     @Override\r
211                     public boolean isCanceled() {\r
212                         return monitor.isCanceled();\r
213                     }\r
214                 });\r
215                 \r
216                 setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);\r
217                 setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));\r
218                 setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());\r
219                 setProperty(MigrationStateKeys.CURRENT_TG, null);\r
220 \r
221                 return getProperty(key);\r
222             }\r
223 \r
224             final TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS);\r
225             if(tgs != null) {\r
226 \r
227                 final Resource indexRoot = session.syncRequest(new WriteResultRequest<Resource>() {\r
228                     @Override\r
229                     public Resource perform(WriteGraph graph) throws DatabaseException {\r
230                         if(!updateDependencies)\r
231                             Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
232                         return createTemporaryRoot(graph);\r
233                     }\r
234                 });\r
235 \r
236                 IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot));\r
237                 IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) {\r
238                         @Override\r
239                         public Resource getTarget() {\r
240                                 return indexRoot;\r
241                         }\r
242                         @Override\r
243                     public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {\r
244                         super.beforeWrite(graph, process);\r
245                         if(!updateDependencies)\r
246                             Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
247                     }\r
248                         @Override\r
249                     public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {\r
250                         super.afterWrite(graph, process);\r
251                         Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS);\r
252                         if(storeResources != null && storeResources) {\r
253                                 long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class));\r
254                                 setProperty(MigrationStateKeys.RESOURCE_IDS, ids);\r
255                         }\r
256                     }\r
257                                 };\r
258                                 // Make sure that the supplied advisor is redirected to temp\r
259                                 advisor.redirect(indexRoot);\r
260                                 \r
261                 TransferableGraphs.importGraph1(session, tgs, advisor, new TGStatusMonitor() {\r
262                     @Override\r
263                     public void status(int percentage) {\r
264                         monitor.subTask("Importing model from file (" + percentage + "%)");\r
265                     }\r
266                     @Override\r
267                     public boolean isCanceled() {\r
268                         return monitor.isCanceled();\r
269                     }\r
270                 });\r
271 \r
272                 setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);\r
273                 setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));\r
274                 setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());\r
275                 setProperty(MigrationStateKeys.CURRENT_TG, null);\r
276 \r
277                 return getProperty(key);\r
278 \r
279             }\r
280 \r
281         } else if (MigrationStateKeys.UPDATE_DEPENDENCIES.equals(key)) {\r
282 \r
283             return null;\r
284 \r
285         }\r
286 \r
287         return null;\r
288 \r
289         }\r
290 \r
291         @Override\r
292         public <T> void setProperty(String key, T value) {\r
293                 properties.put(key, value);\r
294         }\r
295 \r
296         @Override\r
297         public void dispose() {\r
298                 // Close all possible open file handles\r
299                 try {\r
300                         StreamingTransferableGraphFileReader tgs = probeProperty(MigrationStateKeys.CURRENT_TGS_READER);\r
301                         uncheckedClose(tgs);\r
302                 } catch (DatabaseException e) {\r
303                         Logger.defaultLogError(e);\r
304                 }\r
305         }\r
306 \r
307         private static void uncheckedClose(ByteFileReader closeable) {\r
308                 try {\r
309                         if (closeable != null)\r
310                                 closeable.close();\r
311                 } catch (IOException e) {\r
312                         //ignore\r
313                 }\r
314         }\r
315 \r
316     private Resource createTemporaryRoot(WriteGraph graph) throws DatabaseException {\r
317         Layer0 L0 = Layer0.getInstance(graph);\r
318         Resource project = SimanticsInternal.getProject();\r
319         Resource root = graph.getPossibleObject(project, L0.PartOf);\r
320         Resource temp = Layer0Utils.getPossibleChild(graph, root, "Temp");\r
321         if (temp == null) \r
322             throw new AssumptionException("Temporary folder 'Temp' not found under " + graph.getPossibleURI(root));\r
323 \r
324         Resource indexRoot = graph.newResource();\r
325         String indexRootName = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date());\r
326         graph.claim(indexRoot, L0.InstanceOf, L0.IndexRoot);\r
327         graph.addLiteral(indexRoot, L0.HasName, L0.String, indexRootName, Bindings.STRING);\r
328         graph.claim(temp, L0.ConsistsOf, indexRoot);\r
329         return indexRoot;\r
330     }\r
331 \r
332 }\r