private void CheckLocalFile(string filePath, IFolder remoteFolder, IList<string> remoteFiles)
{
SleepWhileSuspended();
try
{
if (Utils.IsSymlink(new FileInfo(filePath)))
{
Logger.Info("Skipping symbolic linked file: " + filePath);
return;
}
var item = database.GetSyncItemFromLocalPath(filePath);
if (null == item)
{
// The file has been recently created locally (not synced from server).
item = SyncItemFactory.CreateFromLocalPath(filePath, false, repoInfo, database);
}
string fileName = item.LocalLeafname;
if (Utils.WorthSyncing(Path.GetDirectoryName(filePath), fileName, repoInfo))
{
if (remoteFiles != null &&
! remoteFiles.Contains(fileName))
{
// This local file is not on the CMIS server now, so
// check whether it used to exist on server or not.
if (database.ContainsLocalFile(filePath))
{
if (database.LocalFileHasChanged(filePath))
{
// If file has changed locally, move to 'your_version' and warn about conflict
if (BIDIRECTIONAL)
{
// Local file was updated, sync up.
Logger.Info("Uploading locally edited remotely removed file from the repository: " + filePath);
activityListener.ActivityStarted();
UploadFile(filePath, remoteFolder);
activityListener.ActivityStopped();
}
else
{
Logger.Info("Conflict with file: " + filePath + ", backing up locally modified version.");
activityListener.ActivityStarted();
// Rename locally modified file.
String newFilePath = Utils.CreateConflictFilename(filePath, repoInfo.User);
// The file might be ReadOnly, so make it writable first, otherwise the move will fail.
File.SetAttributes(filePath, FileAttributes.Normal); // TODO use Utils.DeleteEvenIfReadOnly
File.Move(filePath, newFilePath);
// Delete file from database.
database.RemoveFile(item);
repo.OnConflictResolved();
activityListener.ActivityStopped();
}
}
else
{
// File has been deleted on server, so delete it locally.
Logger.Info("Removing remotely deleted file: " + filePath);
activityListener.ActivityStarted();
// The file might be ReadOnly, so make it writable first, otherwise removal will fail.
File.SetAttributes(filePath, FileAttributes.Normal); // TODO use Utils.DeleteEvenIfReadOnly
// Delete from the local filesystem.
File.Delete(filePath);
// Delete file from database.
database.RemoveFile(item);
activityListener.ActivityStopped();
}
}
else
{
if (BIDIRECTIONAL)
{
// New file, sync up.
Logger.Info("Uploading file absent on repository: " + filePath);
activityListener.ActivityStarted();
UploadFile(filePath, remoteFolder);
activityListener.ActivityStopped();
}
}
}
else
{
// The file exists both on server and locally.
if (database.LocalFileHasChanged(filePath))
{
if (BIDIRECTIONAL)
{
// Upload new version of file content.
Logger.Info("Uploading file update on repository: " + filePath);
activityListener.ActivityStarted();
UpdateFile(filePath, remoteFolder);
activityListener.ActivityStopped();
}
}
}
}
}
catch (Exception e)
{
ProcessRecoverableException("Could not crawl sync local file: " + filePath, e);
}
}