diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/AbstractTransferManager.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/AbstractTransferManager.java index 69fa42126..dc5152673 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/AbstractTransferManager.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/AbstractTransferManager.java @@ -19,6 +19,7 @@ import java.io.File; import java.io.IOException; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -33,7 +34,7 @@ import org.syncany.plugins.StorageTestResult; import org.syncany.plugins.transfer.files.RemoteFile; import org.syncany.plugins.transfer.files.TransactionRemoteFile; -import org.syncany.plugins.transfer.to.TransactionActionTO; +import org.syncany.plugins.transfer.to.ActionTO; import org.syncany.plugins.transfer.to.TransactionTO; /** @@ -104,6 +105,22 @@ public StorageTestResult test(boolean testCreateTarget) { return result; } + public void cleanTransactions(String machineName) throws StorageException { + Map transactions = getTransactionTOs(); + for (TransactionTO transaction : transactions.keySet()) { + if (transaction.getMachineName().equals(machineName)) { + // Delete all permanent or temporary files in this transaction. + for (ActionTO action : transaction.getActions()) { + delete(action.getRemoteFile()); + delete(action.getTempRemoteFile()); + } + + // Get corresponding remote file of transaction and delete it. + delete(transactions.get(transaction)); + } + } + } + /** * Returns a Set of all files that are not temporary, but are listed in a * transaction file. These belong to an unfinished transaction and should be @@ -111,10 +128,21 @@ public StorageTestResult test(boolean testCreateTarget) { */ protected Set getFilesInTransactions() throws StorageException { Set filesInTransaction = new HashSet(); - Map transactionFiles = list(TransactionRemoteFile.class); + Set transactions = getTransactionTOs().keySet(); + + for (TransactionTO transaction : transactions) { + for (ActionTO action : transaction.getActions()) { + filesInTransaction.add(action.getRemoteFile()); + } + } + return filesInTransaction; + } + + private Map getTransactionTOs() throws StorageException{ + Map transactionFiles = list(TransactionRemoteFile.class); + Map transactions = new HashMap(); for (TransactionRemoteFile transaction : transactionFiles.values()) { - List transactionActions = null; try { File transactionFile = createTempFile("transaction"); @@ -128,18 +156,13 @@ protected Set getFilesInTransactions() throws StorageException { TransactionTO transactionTO = serializer.read(TransactionTO.class, transactionFileStr); // Extract final locations - transactionActions = transactionTO.getTransactionActions(); + transactions.put(transactionTO, transaction); transactionFile.delete(); } catch (Exception e) { throw new StorageException("Failed to read transactionFile", e); } - - for (TransactionActionTO transactionAction : transactionActions) { - filesInTransaction.add(transactionAction.getRemoteFile()); - } } - - return filesInTransaction; + return transactions; } } diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/RemoteTransaction.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/RemoteTransaction.java index cdf180376..4ccd64137 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/RemoteTransaction.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/RemoteTransaction.java @@ -31,7 +31,7 @@ import org.syncany.plugins.transfer.files.RemoteFile; import org.syncany.plugins.transfer.files.TempRemoteFile; import org.syncany.plugins.transfer.files.TransactionRemoteFile; -import org.syncany.plugins.transfer.to.TransactionActionTO; +import org.syncany.plugins.transfer.to.ActionTO; import org.syncany.plugins.transfer.to.TransactionTO; /** @@ -63,12 +63,12 @@ public void add(File localFile, RemoteFile remoteFile) throws StorageException { logger.log(Level.INFO, "Adding file to transaction: " + localFile); logger.log(Level.INFO, " -> Temp. remote file: " + temporaryRemoteFile + ", final location: " + remoteFile); - TransactionActionTO action = new TransactionActionTO(); - action.setType(TransactionActionTO.TYPE_UPLOAD); + ActionTO action = new ActionTO(); + action.setType(ActionTO.TYPE_UPLOAD); action.setLocalTempLocation(localFile); action.setRemoteLocation(remoteFile); action.setRemoteTempLocation(temporaryRemoteFile); - transactionTO.addTransactionAction(action); + transactionTO.addAction(action); } /** @@ -83,14 +83,14 @@ public void commit() throws StorageException { transferManager.upload(localTransactionFile, remoteTransactionFile); - for (TransactionActionTO action : transactionTO.getTransactionActions()) { + for (ActionTO action : transactionTO.getActions()) { File localFile = action.getLocalTempLocation(); RemoteFile tempRemoteFile = action.getTempRemoteFile(); logger.log(Level.INFO, "- Uploading {0} to temp. file {1} ...", new Object[] { localFile, tempRemoteFile }); transferManager.upload(localFile, tempRemoteFile); } - for (TransactionActionTO action : transactionTO.getTransactionActions()) { + for (ActionTO action : transactionTO.getActions()) { RemoteFile tempRemoteFile = action.getTempRemoteFile(); RemoteFile finalRemoteFile = action.getRemoteFile(); logger.log(Level.INFO, "- Moving temp. file {0} to final location {1} ...", new Object[] { tempRemoteFile, finalRemoteFile }); diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/RetriableTransferManager.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/RetriableTransferManager.java index ef453bc96..ee0d96008 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/RetriableTransferManager.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/RetriableTransferManager.java @@ -138,6 +138,17 @@ public Object execute() throws StorageException { } }); } + + @Override + public void cleanTransactions(final String machineName) throws StorageException { + retryMethod(new RetriableMethod() { + @Override + public Object execute() throws StorageException { + underlyingTransferManager.cleanTransactions(machineName); + return null; + } + }); + } @Override public StorageTestResult test(boolean testCreateTarget) { @@ -218,4 +229,6 @@ private Object retryMethod(RetriableMethod retryableMethod) throws StorageExcept } } } + + } diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/TransferManager.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/TransferManager.java index f068e630d..07bb065a1 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/TransferManager.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/TransferManager.java @@ -153,6 +153,17 @@ public interface TransferManager { */ public Map list(Class remoteFileClass) throws StorageException; + + /** + * Deletes all files that are related to transactions by the given machineName. + * + * @param machineName Name filter: this function only operations on transactions + * by this client. + * @throws StorageException If the connection fails due to no Internet connection, + * authentication errors, etc + */ + public void cleanTransactions(String machineName) throws StorageException; + /** * Tests whether the repository parameters are valid. In particular, the method tests * whether a target (folder, bucket, etc.) exists or, if not, whether it can be created. diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionActionTO.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/ActionTO.java similarity index 95% rename from syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionActionTO.java rename to syncany-lib/src/main/java/org/syncany/plugins/transfer/to/ActionTO.java index 5ef8c2e7a..eb1948eae 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionActionTO.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/ActionTO.java @@ -36,8 +36,8 @@ @Root(name="transactionAction") @Namespace(reference="http://syncany.org/transaction/action/1") -public class TransactionActionTO { - private static final Logger logger = Logger.getLogger(TransactionActionTO.class.getSimpleName()); +public class ActionTO { + private static final Logger logger = Logger.getLogger(ActionTO.class.getSimpleName()); public static final String TYPE_UPLOAD = "UPLOAD"; public static final String TYPE_DELETE = "DELETE"; diff --git a/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionTO.java b/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionTO.java index b6bd85b9c..1ff6167cc 100644 --- a/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionTO.java +++ b/syncany-lib/src/main/java/org/syncany/plugins/transfer/to/TransactionTO.java @@ -46,7 +46,7 @@ public class TransactionTO { private String machineName; @ElementList(entry="action") - private List transactionActionTOs; + private List actionTOs; public TransactionTO() { @@ -55,18 +55,18 @@ public TransactionTO() { public TransactionTO(String machineName) { this.machineName = machineName; - transactionActionTOs = new ArrayList(); + actionTOs = new ArrayList(); } public String getMachineName() { return machineName; } - public List getTransactionActions() { - return transactionActionTOs; + public List getActions() { + return actionTOs; } - public void addTransactionAction(TransactionActionTO transactionAction) { - transactionActionTOs.add(transactionAction); + public void addAction(ActionTO transactionAction) { + actionTOs.add(transactionAction); } }