-package org.simantics.backup;\r
-\r
-import java.io.IOException;\r
-import java.nio.file.Files;\r
-import java.nio.file.Path;\r
-import java.nio.file.Paths;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-import java.util.concurrent.ExecutionException;\r
-import java.util.concurrent.Future;\r
-import java.util.function.Consumer;\r
-\r
-import org.eclipse.core.runtime.CoreException;\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.MultiStatus;\r
-import org.eclipse.core.runtime.Status;\r
-import org.osgi.framework.InvalidSyntaxException;\r
-import org.osgi.framework.ServiceReference;\r
-\r
-/**\r
- * @author Jani Simomaa\r
- */\r
-public class BackupProviderService {\r
-\r
- private static volatile int threadCounter = 0;\r
-\r
- public static void backup(String targetPath, int revision) throws BackupException {\r
- backup(Paths.get(targetPath), revision, null);\r
- }\r
- \r
- /**\r
- * @param targetPath\r
- * @param revision\r
- * @param callback \r
- * @throws BackupException \r
- */\r
- public static void backup(Path targetPath, int revision, Consumer<BackupException> callback) throws BackupException {\r
- List<IBackupProvider> providers = getBackupProviders();\r
- try {\r
- if (!Files.exists(targetPath))\r
- Files.createDirectories(targetPath);\r
- Backups.lock(providers);\r
- new Thread(() -> {\r
- boolean unlockedAlready = false;\r
- BackupException problem = null;\r
- try {\r
- List<Future<BackupException>> backups = Backups.syncBackup(providers, targetPath, revision);\r
- // Unlock providers at this stage\r
- Backups.unlock(providers);\r
- unlockedAlready = true;\r
- \r
- // Wait for all providers to complete their work.\r
- List<Exception> exceptions = new ArrayList<>(backups.size());\r
- for (Future<BackupException> f : backups) {\r
- try {\r
- Exception e = f.get();\r
- if (e != null)\r
- exceptions.add(e);\r
- } catch (InterruptedException | ExecutionException e) {\r
- exceptions.add(e);\r
- }\r
- }\r
-\r
- // Throw BackupException if any of the backup operations failed.\r
- if (!exceptions.isEmpty()) {\r
- IStatus[] ss = exceptions.stream()\r
- .map(e -> new Status(IStatus.ERROR, Activator.BUNDLE_ID, e.getMessage(), e))\r
- .toArray(IStatus[]::new);\r
- problem = new BackupException(new CoreException(new MultiStatus(Activator.BUNDLE_ID, 0, ss,\r
- "Backup operation(s) failed to complete.", null)));\r
- }\r
-\r
- } catch (BackupException e) {\r
- problem = e;\r
- } catch (Throwable t) {\r
- problem = new BackupException(t);\r
- } finally {\r
- if (!unlockedAlready)\r
- Backups.unlock(providers);\r
- }\r
- if (callback != null)\r
- callback.accept(problem);\r
- }, "Backup thread " + (++threadCounter)).start();\r
- } catch (IOException e) {\r
- throw new BackupException(e);\r
- }\r
- }\r
-\r
- /**\r
- * @param fromPath\r
- * @param revision\r
- */\r
- public static void restore(Path fromPath, int revision) throws BackupException {\r
- restore(getBackupProviders(), fromPath, revision);\r
- }\r
-\r
- private static void restore(Collection<IBackupProvider> providers, Path fromPath, int revision) throws BackupException {\r
- for (IBackupProvider provider : providers)\r
- provider.restore(fromPath, revision);\r
- }\r
-\r
- private static List<IBackupProvider> getBackupProviders() throws BackupException {\r
- try {\r
- List<IBackupProvider> results = new ArrayList<>();\r
- Collection<ServiceReference<IBackupProvider>> backupProviders = Activator.getContext().getServiceReferences(IBackupProvider.class, null);\r
- for (ServiceReference<IBackupProvider> reference : backupProviders) {\r
- results.add(Activator.getContext().getService(reference));\r
- }\r
- return results;\r
- } catch (InvalidSyntaxException e) {\r
- throw new BackupException("Failed to enumerate backup providers.", e);\r
- }\r
- }\r
-\r
-}\r
+package org.simantics.backup;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.function.Consumer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * @author Jani Simomaa
+ */
+public class BackupProviderService {
+
+ private static volatile int threadCounter = 0;
+
+ public static void backup(String targetPath, int revision) throws BackupException {
+ backup(Paths.get(targetPath), revision, null);
+ }
+
+ /**
+ * @param targetPath
+ * @param revision
+ * @param callback
+ * @throws BackupException
+ */
+ public static void backup(Path targetPath, int revision, Consumer<BackupException> callback) throws BackupException {
+ List<IBackupProvider> providers = getBackupProviders();
+ try {
+ if (!Files.exists(targetPath))
+ Files.createDirectories(targetPath);
+ Backups.lock(providers);
+ new Thread(() -> {
+ boolean unlockedAlready = false;
+ BackupException problem = null;
+ try {
+ List<Future<BackupException>> backups = Backups.syncBackup(providers, targetPath, revision);
+ // Unlock providers at this stage
+ Backups.unlock(providers);
+ unlockedAlready = true;
+
+ // Wait for all providers to complete their work.
+ List<Exception> exceptions = new ArrayList<>(backups.size());
+ for (Future<BackupException> f : backups) {
+ try {
+ Exception e = f.get();
+ if (e != null)
+ exceptions.add(e);
+ } catch (InterruptedException | ExecutionException e) {
+ exceptions.add(e);
+ }
+ }
+
+ // Throw BackupException if any of the backup operations failed.
+ if (!exceptions.isEmpty()) {
+ IStatus[] ss = exceptions.stream()
+ .map(e -> new Status(IStatus.ERROR, Activator.BUNDLE_ID, e.getMessage(), e))
+ .toArray(IStatus[]::new);
+ problem = new BackupException(new CoreException(new MultiStatus(Activator.BUNDLE_ID, 0, ss,
+ "Backup operation(s) failed to complete.", null)));
+ }
+
+ } catch (BackupException e) {
+ problem = e;
+ } catch (Throwable t) {
+ problem = new BackupException(t);
+ } finally {
+ if (!unlockedAlready)
+ Backups.unlock(providers);
+ }
+ if (callback != null)
+ callback.accept(problem);
+ }, "Backup thread " + (++threadCounter)).start();
+ } catch (IOException e) {
+ throw new BackupException(e);
+ }
+ }
+
+ /**
+ * @param fromPath
+ * @param revision
+ */
+ public static void restore(Path fromPath, int revision) throws BackupException {
+ restore(getBackupProviders(), fromPath, revision);
+ }
+
+ private static void restore(Collection<IBackupProvider> providers, Path fromPath, int revision) throws BackupException {
+ for (IBackupProvider provider : providers)
+ provider.restore(fromPath, revision);
+ }
+
+ private static List<IBackupProvider> getBackupProviders() throws BackupException {
+ try {
+ List<IBackupProvider> results = new ArrayList<>();
+ Collection<ServiceReference<IBackupProvider>> backupProviders = Activator.getContext().getServiceReferences(IBackupProvider.class, null);
+ for (ServiceReference<IBackupProvider> reference : backupProviders) {
+ results.add(Activator.getContext().getService(reference));
+ }
+ return results;
+ } catch (InvalidSyntaxException e) {
+ throw new BackupException("Failed to enumerate backup providers.", e);
+ }
+ }
+
+}