LsRemoteOperation.java
/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.operations.ls_remote;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.syncany.config.Config;
import org.syncany.config.LocalEventBus;
import org.syncany.database.SqlDatabase;
import org.syncany.operations.Operation;
import org.syncany.operations.daemon.messages.LsRemoteEndSyncExternalEvent;
import org.syncany.operations.daemon.messages.LsRemoteStartSyncExternalEvent;
import org.syncany.plugins.transfer.StorageException;
import org.syncany.plugins.transfer.TransferManager;
import org.syncany.plugins.transfer.TransferManagerFactory;
import org.syncany.plugins.transfer.features.PathAware;
import org.syncany.plugins.transfer.files.DatabaseRemoteFile;
/**
* The list remote operation queries the transfer manager for any unknown
* {@link DatabaseRemoteFile}s.
*
* <p>It first uses a {@link TransferManager} to list all remote databases and then
* uses the local list of known databases to filter already processed files. The local
* list of known databases is loaded.
*
* @author Philipp C. Heckel (philipp.heckel@gmail.com)
*/
public class LsRemoteOperation extends Operation {
private static final Logger logger = Logger.getLogger(LsRemoteOperation.class.getSimpleName());
private TransferManager loadedTransferManager;
private SqlDatabase localDatabase;
private LocalEventBus eventBus;
public LsRemoteOperation(Config config) {
this(config, null);
}
public LsRemoteOperation(Config config, TransferManager transferManager) {
super(config);
this.loadedTransferManager = transferManager;
this.localDatabase = new SqlDatabase(config);
this.eventBus = LocalEventBus.getInstance();
}
@Override
public LsRemoteOperationResult execute() throws Exception {
logger.log(Level.INFO, "");
logger.log(Level.INFO, "Running 'Remote Status' at client " + config.getMachineName() + " ...");
logger.log(Level.INFO, "--------------------------------------------");
eventBus.post(new LsRemoteStartSyncExternalEvent(config.getLocalDir().getAbsolutePath()));
TransferManager transferManager = createTransferManager(loadedTransferManager);
List<DatabaseRemoteFile> knownDatabases = localDatabase.getKnownDatabases();
List<DatabaseRemoteFile> unknownRemoteDatabases = listUnknownRemoteDatabases(transferManager, knownDatabases);
transferManager.disconnect();
boolean hasChanges = unknownRemoteDatabases.size() > 0;
eventBus.post(new LsRemoteEndSyncExternalEvent(config.getLocalDir().getAbsolutePath(), hasChanges));
return new LsRemoteOperationResult(new ArrayList<>(unknownRemoteDatabases));
}
private TransferManager createTransferManager(TransferManager loadedTransferManager) throws StorageException {
if (loadedTransferManager != null) {
return loadedTransferManager;
}
else {
return TransferManagerFactory
.build(config)
.withFeature(PathAware.class)
.asDefault();
}
}
private List<DatabaseRemoteFile> listUnknownRemoteDatabases(TransferManager transferManager, List<DatabaseRemoteFile> knownDatabases)
throws StorageException {
logger.log(Level.INFO, "Retrieving remote database list.");
List<DatabaseRemoteFile> unknownRemoteDatabases = new ArrayList<DatabaseRemoteFile>();
// List all remote database files
Map<String, DatabaseRemoteFile> remoteDatabaseFiles = transferManager.list(DatabaseRemoteFile.class);
for (DatabaseRemoteFile remoteDatabaseFile : remoteDatabaseFiles.values()) {
// This does NOT filter 'lock' files!
if (knownDatabases.contains(remoteDatabaseFile)) {
logger.log(Level.INFO, "- Remote database {0} is already known (in local database). Ignoring.", remoteDatabaseFile.getName());
}
else {
logger.log(Level.INFO, "- Remote database {0} is new.", remoteDatabaseFile.getName());
unknownRemoteDatabases.add(remoteDatabaseFile);
}
}
return unknownRemoteDatabases;
}
}