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.down.actions;
019
020import org.syncany.config.Config;
021import org.syncany.database.FileVersion;
022import org.syncany.database.FileVersion.FileStatus;
023import org.syncany.database.FileVersionComparator;
024import org.syncany.database.MemoryDatabase;
025
026public class DeleteFileSystemAction extends FileSystemAction {
027        public DeleteFileSystemAction(Config config, FileVersion fromFileVersion, FileVersion toDeleteFileVersion, MemoryDatabase winningDatabase) {
028                super(config, winningDatabase, fromFileVersion, toDeleteFileVersion);
029        }
030
031        /**
032         * Deletes a file locally and/or creates a conflicting file if the
033         * file does not match the expectations. There are two major cases:
034         * 
035         * <p>Normal case: The file version of the to-be-deleted file is known. If the file is 
036         * as expected, it is deleted; if not and the file exists, a conflict file is created.
037         * 
038         * <p>Special case: The file version of the to-be-deleted file in unknown. 
039         * In case to-be-deleted-file exists locally, we need to compare it to
040         * the local file (especially its checksum!). The {@link FileVersionComparator}
041         * does, however, perform a cancelling test in which {@link FileVersion}s marked as
042         * 'DELETED' are not compared in detail (no checksum/attribute/etc. comparisons). To
043         * circumvent this behavior, we pretend the file has just changed and do the comparison.
044         * If the to-be-deleted file and file version are equal, the local file is deleted. 
045         * Otherwise, a conflict file is created. 
046         */
047        @Override
048        public FileSystemActionResult execute() throws Exception {
049                // Special case: locally unknown file to be deleted             
050                if (fileVersion1 == null) {
051                        if (fileExists(fileVersion2)) {
052                                FileVersion pretendChangedFileVersion = fileVersion2.clone();
053                                pretendChangedFileVersion.setStatus(FileStatus.CHANGED); 
054                                
055                                if (fileAsExpected(pretendChangedFileVersion)) {
056                                        deleteFile(fileVersion2);                                       
057                                }
058                                else {
059                                        moveToConflictFile(fileVersion2);                                       
060                                }
061                        }                       
062                }
063                
064                // Normal case: locally known file to be deleted
065                else {
066                        if (!fileAsExpected(fileVersion1)) {
067                                if (fileExists(fileVersion1)) {
068                                        moveToConflictFile(fileVersion2);       
069                                }
070                        }
071                        else {
072                                deleteFile(fileVersion1);       
073                        }
074                }
075                                        
076                return new FileSystemActionResult();
077        }
078
079        @Override
080        public String toString() {
081                return "DeleteFileSystemAction [file1=" + fileVersion1 + ", file2=" + fileVersion2 + "]";
082        }
083}
084