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;
019
020import java.util.ArrayList;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024import java.util.logging.Level;
025import java.util.logging.Logger;
026
027import org.syncany.config.Config;
028import org.syncany.database.FileVersion;
029import org.syncany.database.FileVersion.FileType;
030import org.syncany.database.PartialFileHistory;
031import org.syncany.database.PartialFileHistory.FileHistoryId;
032import org.syncany.database.SqlDatabase;
033import org.syncany.operations.Operation;
034
035import com.google.common.base.Function;
036import com.google.common.collect.Collections2;
037
038public class LsOperation extends Operation {
039        private static final Logger logger = Logger.getLogger(LsOperation.class.getSimpleName());
040        private LsOperationOptions options;
041        private SqlDatabase localDatabase;
042
043        public LsOperation(Config config, LsOperationOptions options) {
044                super(config);
045
046                this.options = options;
047                this.localDatabase = new SqlDatabase(config);
048        }
049
050        @Override
051        public LsOperationResult execute() throws Exception {
052                logger.log(Level.INFO, "");
053                logger.log(Level.INFO, "Running 'Ls' at client " + config.getMachineName() + " ...");
054                logger.log(Level.INFO, "--------------------------------------------");
055
056                String pathExpression = parsePathExpression(options.getPathExpression(), options.isFileHistoryId());
057                Set<FileType> fileTypes = options.getFileTypes();
058
059                List<FileVersion> fileList = localDatabase.getFileList(pathExpression, options.getDate(), options.isFileHistoryId(), options.isRecursive(), options.isDeleted(), fileTypes);
060                Map<FileHistoryId, PartialFileHistory> fileHistories = null;
061
062                if (options.isFetchHistories()) {
063                        fileHistories = fetchFileHistories(fileList);
064                }
065
066                return new LsOperationResult(fileList, fileHistories);
067        }
068
069        private Map<FileHistoryId, PartialFileHistory> fetchFileHistories(List<FileVersion> fileTree) {
070                // Get file history IDs
071                List<FileHistoryId> fileHistoryIds = new ArrayList<>(Collections2.transform(fileTree, new Function<FileVersion, FileHistoryId>() {
072                        @Override
073                        public FileHistoryId apply(FileVersion fileVersion) {
074                                return fileVersion.getFileHistoryId();
075                        }
076                }));
077
078                return localDatabase.getFileHistories(fileHistoryIds);
079        }
080
081        private String parsePathExpression(String pathExpression, boolean isFileHistoryId) {
082                if (pathExpression != null) {
083                        if (isFileHistoryId) {
084                                String randomFileHistoryId = FileHistoryId.secureRandomFileId().toString();
085                                boolean isFullLength = pathExpression.length() == randomFileHistoryId.length();
086                                
087                                if (isFullLength) {
088                                        return pathExpression;
089                                }
090                                else {
091                                        return pathExpression + "%";
092                                }
093                        }
094                        else {
095                                if (pathExpression.contains("^") || pathExpression.contains("*")) {
096                                        return pathExpression.replace('^', '%').replace('*', '%');
097                                }
098                                else {
099                                        return pathExpression + "%";
100                                }
101                        }
102                }
103                else {
104                        return null;
105                }
106        }
107}