X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.backup%2Fsrc%2Forg%2Fsimantics%2Fbackup%2FBackupProviderService.java;fp=bundles%2Forg.simantics.backup%2Fsrc%2Forg%2Fsimantics%2Fbackup%2FBackupProviderService.java;h=32230419a40a09fe449e849946f90aa2337c43c0;hb=4e40f9793cc18f08f1fa6c96d9bb4f42408997b4;hp=0000000000000000000000000000000000000000;hpb=9a175feb652b2b7bba7afa540831b9076be3c10e;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.backup/src/org/simantics/backup/BackupProviderService.java b/bundles/org.simantics.backup/src/org/simantics/backup/BackupProviderService.java new file mode 100644 index 000000000..32230419a --- /dev/null +++ b/bundles/org.simantics.backup/src/org/simantics/backup/BackupProviderService.java @@ -0,0 +1,116 @@ +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 callback) throws BackupException { + List providers = getBackupProviders(); + try { + if (!Files.exists(targetPath)) + Files.createDirectories(targetPath); + Backups.lock(providers); + new Thread(() -> { + boolean unlockedAlready = false; + BackupException problem = null; + try { + List> 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 exceptions = new ArrayList<>(backups.size()); + for (Future 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 providers, Path fromPath, int revision) throws BackupException { + for (IBackupProvider provider : providers) + provider.restore(fromPath, revision); + } + + private static List getBackupProviders() throws BackupException { + try { + List results = new ArrayList<>(); + Collection> backupProviders = Activator.getContext().getServiceReferences(IBackupProvider.class, null); + for (ServiceReference reference : backupProviders) { + results.add(Activator.getContext().getService(reference)); + } + return results; + } catch (InvalidSyntaxException e) { + throw new BackupException("Failed to enumerate backup providers.", e); + } + } + +}