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.operations.ls_remote; 019 020import java.util.ArrayList; 021import java.util.List; 022import java.util.Map; 023import java.util.logging.Level; 024import java.util.logging.Logger; 025 026import org.syncany.config.Config; 027import org.syncany.config.LocalEventBus; 028import org.syncany.database.SqlDatabase; 029import org.syncany.operations.Operation; 030import org.syncany.operations.daemon.messages.LsRemoteEndSyncExternalEvent; 031import org.syncany.operations.daemon.messages.LsRemoteStartSyncExternalEvent; 032import org.syncany.plugins.transfer.StorageException; 033import org.syncany.plugins.transfer.TransferManager; 034import org.syncany.plugins.transfer.TransferManagerFactory; 035import org.syncany.plugins.transfer.features.PathAware; 036import org.syncany.plugins.transfer.files.DatabaseRemoteFile; 037 038/** 039 * The list remote operation queries the transfer manager for any unknown 040 * {@link DatabaseRemoteFile}s. 041 * 042 * <p>It first uses a {@link TransferManager} to list all remote databases and then 043 * uses the local list of known databases to filter already processed files. The local 044 * list of known databases is loaded. 045 * 046 * @author Philipp C. Heckel (philipp.heckel@gmail.com) 047 */ 048public class LsRemoteOperation extends Operation { 049 private static final Logger logger = Logger.getLogger(LsRemoteOperation.class.getSimpleName()); 050 051 private TransferManager loadedTransferManager; 052 private SqlDatabase localDatabase; 053 private LocalEventBus eventBus; 054 055 public LsRemoteOperation(Config config) { 056 this(config, null); 057 } 058 059 public LsRemoteOperation(Config config, TransferManager transferManager) { 060 super(config); 061 062 this.loadedTransferManager = transferManager; 063 this.localDatabase = new SqlDatabase(config); 064 this.eventBus = LocalEventBus.getInstance(); 065 } 066 067 @Override 068 public LsRemoteOperationResult execute() throws Exception { 069 logger.log(Level.INFO, ""); 070 logger.log(Level.INFO, "Running 'Remote Status' at client " + config.getMachineName() + " ..."); 071 logger.log(Level.INFO, "--------------------------------------------"); 072 073 eventBus.post(new LsRemoteStartSyncExternalEvent(config.getLocalDir().getAbsolutePath())); 074 075 TransferManager transferManager = createTransferManager(loadedTransferManager); 076 077 List<DatabaseRemoteFile> knownDatabases = localDatabase.getKnownDatabases(); 078 List<DatabaseRemoteFile> unknownRemoteDatabases = listUnknownRemoteDatabases(transferManager, knownDatabases); 079 080 transferManager.disconnect(); 081 082 boolean hasChanges = unknownRemoteDatabases.size() > 0; 083 eventBus.post(new LsRemoteEndSyncExternalEvent(config.getLocalDir().getAbsolutePath(), hasChanges)); 084 085 return new LsRemoteOperationResult(new ArrayList<>(unknownRemoteDatabases)); 086 } 087 088 private TransferManager createTransferManager(TransferManager loadedTransferManager) throws StorageException { 089 if (loadedTransferManager != null) { 090 return loadedTransferManager; 091 } 092 else { 093 return TransferManagerFactory 094 .build(config) 095 .withFeature(PathAware.class) 096 .asDefault(); 097 } 098 } 099 100 private List<DatabaseRemoteFile> listUnknownRemoteDatabases(TransferManager transferManager, List<DatabaseRemoteFile> knownDatabases) 101 throws StorageException { 102 logger.log(Level.INFO, "Retrieving remote database list."); 103 104 List<DatabaseRemoteFile> unknownRemoteDatabases = new ArrayList<DatabaseRemoteFile>(); 105 106 // List all remote database files 107 Map<String, DatabaseRemoteFile> remoteDatabaseFiles = transferManager.list(DatabaseRemoteFile.class); 108 109 for (DatabaseRemoteFile remoteDatabaseFile : remoteDatabaseFiles.values()) { 110 // This does NOT filter 'lock' files! 111 if (knownDatabases.contains(remoteDatabaseFile)) { 112 logger.log(Level.INFO, "- Remote database {0} is already known (in local database). Ignoring.", remoteDatabaseFile.getName()); 113 } 114 else { 115 logger.log(Level.INFO, "- Remote database {0} is new.", remoteDatabaseFile.getName()); 116 unknownRemoteDatabases.add(remoteDatabaseFile); 117 } 118 } 119 120 return unknownRemoteDatabases; 121 } 122}