001/* 002 * Syncany, www.syncany.org 003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package org.syncany.plugins.transfer; 019 020import java.io.File; 021import java.io.IOException; 022import java.util.logging.Level; 023import java.util.logging.Logger; 024 025import org.syncany.config.Config; 026import org.syncany.plugins.transfer.features.Retriable; 027import org.syncany.plugins.transfer.features.TransactionAware; 028import org.syncany.util.StringUtil; 029 030/** 031 * Implements basic functionality of a {@link TransferManager} which 032 * can be implemented sub-classes. 033 * 034 * <p>This transfer manager is enhanced with the {@link TransactionAware} 035 * and {@link Retriable} annotations, thereby making it reliable. 036 * 037 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 038 * @author Christian Roth (christian.roth@port17.de) 039 */ 040@TransactionAware 041@Retriable(numberRetries = 3, sleepInterval = 3000) 042public abstract class AbstractTransferManager implements TransferManager { // TODO [medium] Rename this to AbstractReliableTransferManager 043 private static final Logger logger = Logger.getLogger(AbstractTransferManager.class.getSimpleName()); 044 045 protected TransferSettings settings; 046 protected Config config; 047 048 public AbstractTransferManager(TransferSettings settings, Config config) { 049 this.settings = settings; 050 this.config = config; 051 } 052 053 /** 054 * Creates a temporary file, either using the config (if initialized) or 055 * using the global temporary directory. 056 */ 057 protected File createTempFile(String name) throws IOException { 058 if (config == null) { 059 return File.createTempFile(String.format("temp-%s-", name), ".tmp"); 060 } 061 else { 062 return config.getCache().createTempFile(name); 063 } 064 } 065 066 /** 067 * Checks whether the settings given to this transfer manager can be 068 * used to create or connect to a remote repository. 069 * 070 * <p>Tests if the target exists, if it can be written to and if a 071 * repository can be created. 072 */ 073 @Override 074 public StorageTestResult test(boolean testCreateTarget) { 075 logger.log(Level.INFO, "Performing storage test TM.test() ..."); 076 StorageTestResult result = new StorageTestResult(); 077 078 try { 079 logger.log(Level.INFO, "- Running connect() ..."); 080 connect(); 081 082 result.setTargetExists(testTargetExists()); 083 result.setTargetCanWrite(testTargetCanWrite()); 084 result.setRepoFileExists(testRepoFileExists()); 085 086 if (result.isTargetExists()) { 087 result.setTargetCanCreate(true); 088 } 089 else { 090 if (testCreateTarget) { 091 result.setTargetCanCreate(testTargetCanCreate()); 092 } 093 else { 094 result.setTargetCanCreate(false); 095 } 096 } 097 098 result.setTargetCanConnect(true); 099 } 100 catch (StorageException e) { 101 result.setTargetCanConnect(false); 102 result.setErrorMessage(StringUtil.getStackTrace(e)); 103 104 logger.log(Level.INFO, "-> Testing storage failed. Returning " + result, e); 105 } 106 finally { 107 try { 108 disconnect(); 109 } 110 catch (StorageException e) { 111 logger.log(Level.FINE, "Could not disconnect", e); 112 } 113 } 114 115 return result; 116 } 117}