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