1 package org.simantics.backup.db;
\r
3 import java.nio.file.Path;
\r
4 import java.util.ArrayList;
\r
5 import java.util.HashSet;
\r
6 import java.util.List;
\r
7 import java.util.concurrent.Callable;
\r
8 import java.util.concurrent.ExecutionException;
\r
9 import java.util.concurrent.Future;
\r
10 import java.util.concurrent.FutureTask;
\r
12 import org.eclipse.core.runtime.CoreException;
\r
13 import org.eclipse.core.runtime.IStatus;
\r
14 import org.eclipse.core.runtime.MultiStatus;
\r
15 import org.eclipse.core.runtime.Status;
\r
16 import org.simantics.Simantics;
\r
17 import org.simantics.backup.Activator;
\r
18 import org.simantics.backup.BackupException;
\r
19 import org.simantics.backup.Backups;
\r
20 import org.simantics.backup.IBackupProvider;
\r
21 import org.simantics.backup.ontology.BackupResource;
\r
22 import org.simantics.db.ReadGraph;
\r
23 import org.simantics.db.Resource;
\r
24 import org.simantics.db.common.request.UniqueRead;
\r
25 import org.simantics.db.exception.DatabaseException;
\r
26 import org.simantics.db.layer0.adapter.Instances;
\r
27 import org.simantics.db.layer0.util.Layer0Utils;
\r
28 import org.simantics.db.layer0.variable.Variable;
\r
29 import org.simantics.db.layer0.variable.Variables;
\r
31 public class ModelledBackupProvider implements IBackupProvider {
\r
33 List<IBackupProvider> modelledBackups = new ArrayList<>();
\r
35 public ModelledBackupProvider() {
\r
36 // Should this be on the constructor or can there be dynamic ontologies?
\r
37 this.modelledBackups = getModelledBackups();
\r
41 public void lock() throws BackupException {
\r
42 Backups.lock(modelledBackups);
\r
46 public Future<BackupException> backup(Path targetPath, int revision) throws BackupException {
\r
47 final List<Future<BackupException>> backups = new ArrayList<>();
\r
48 final List<Exception> exceptions = new ArrayList<>(backups.size());
\r
49 for (IBackupProvider modelledBackup : modelledBackups) {
\r
51 Future<BackupException> future = modelledBackup.backup(targetPath, revision);
\r
52 backups.add(future);
\r
53 } catch (BackupException e) {
\r
57 FutureTask<BackupException> task = new FutureTask<>(new Callable<BackupException>() {
\r
60 public BackupException call() throws Exception {
\r
61 for (Future<BackupException> f : backups) {
\r
63 Exception exception = f.get();
\r
64 if (exception != null)
\r
65 exceptions.add(exception);
\r
66 } catch (InterruptedException | ExecutionException e) {
\r
70 BackupException problem = null;
\r
71 // Throw BackupException if any of the backup operations failed.
\r
72 if (!exceptions.isEmpty()) {
\r
73 IStatus[] ss = exceptions.stream()
\r
74 .map(e -> new Status(IStatus.ERROR, Activator.BUNDLE_ID, e.getMessage(), e))
\r
75 .toArray(IStatus[]::new);
\r
76 problem = new BackupException(new CoreException(new MultiStatus(Activator.BUNDLE_ID, 0, ss,
\r
77 "Backup operation(s) failed to complete.", null)));
\r
82 new Thread(task).run();
\r
87 public void unlock() throws BackupException {
\r
88 Backups.unlock(modelledBackups);
\r
92 public void restore(Path fromPath, int revision) throws BackupException {
\r
93 for (IBackupProvider modelledBackup : modelledBackups) {
\r
94 modelledBackup.restore(fromPath, revision);
\r
99 private List<IBackupProvider> getModelledBackups() {
\r
100 List<IBackupProvider> modelledProviders = new ArrayList<>(0);
\r
102 modelledProviders = Simantics.getSession().syncRequest(new UniqueRead<List<IBackupProvider>>() {
\r
105 public List<IBackupProvider> perform(ReadGraph graph) throws DatabaseException {
\r
106 BackupResource BACKUP = BackupResource.getInstance(graph);
\r
107 Instances query = graph.adapt(BACKUP.ModelledBackupProvider, Instances.class);
\r
109 HashSet<Resource> providers = new HashSet<>();
\r
111 List<Resource> ontologies = Layer0Utils.listOntologies(graph);
\r
112 for (Resource ontology : ontologies) {
\r
113 for(Resource provider : query.find(graph, ontology)) {
\r
114 providers.add(provider);
\r
117 List<IBackupProvider> modelledBackups = new ArrayList<>();
\r
118 for (Resource provider : providers) {
\r
119 Variable variable = Variables.getVariable(graph, provider);
\r
120 IBackupProvider modelledBackup = variable.getPropertyValue(graph, "instance");
\r
121 modelledBackups.add(modelledBackup);
\r
124 return modelledBackups;
\r
127 } catch (DatabaseException e) {
\r
128 e.printStackTrace();
\r
130 return modelledProviders;
\r