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.cli; 019 020import java.util.ArrayList; 021import java.util.List; 022 023import joptsimple.OptionParser; 024import joptsimple.OptionSet; 025 026import org.syncany.cli.util.CliTableUtil; 027import org.syncany.config.to.FolderTO; 028import org.syncany.operations.OperationResult; 029import org.syncany.operations.daemon.DaemonOperation; 030import org.syncany.operations.daemon.DaemonOperationOptions; 031import org.syncany.operations.daemon.DaemonOperationOptions.DaemonAction; 032import org.syncany.operations.daemon.DaemonOperationResult; 033 034public class DaemonCommand extends Command { 035 private DaemonAction action; 036 037 @Override 038 public CommandScope getRequiredCommandScope() { 039 return CommandScope.ANY; 040 } 041 042 @Override 043 public boolean canExecuteInDaemonScope() { 044 return false; 045 } 046 047 @Override 048 public int execute(String[] operationArgs) throws Exception { 049 DaemonOperationOptions operationOptions = parseOptions(operationArgs); 050 DaemonOperationResult operationResult = new DaemonOperation(operationOptions).execute(); 051 052 printResults(operationResult); 053 054 return 0; 055 } 056 057 @Override 058 public DaemonOperationOptions parseOptions(String[] operationArgs) throws Exception { 059 DaemonOperationOptions operationOptions = new DaemonOperationOptions(); 060 061 OptionParser parser = new OptionParser(); 062 OptionSet options = parser.parse(operationArgs); 063 064 // Files 065 List<?> nonOptionArgs = options.nonOptionArguments(); 066 067 if (nonOptionArgs.size() == 0) { 068 throw new Exception("Invalid syntax, no action given (start, stop, reload, restart, status, force-stop, list, add, remove)."); 069 } 070 071 // <action> 072 String actionStr = nonOptionArgs.get(0).toString(); 073 action = parseDaemonAction(actionStr); 074 075 operationOptions.setAction(action); 076 077 // add|remove (<folder-path> ...) 078 if (action == DaemonAction.ADD || action == DaemonAction.REMOVE) { 079 if (nonOptionArgs.size() < 2) { 080 throw new Exception("Invalid syntax, please specify a folder path."); 081 } 082 083 // <folder-path> ... 084 List<String> watchRoots = new ArrayList<>(); 085 086 for (int i = 1; i < nonOptionArgs.size(); i++) { 087 watchRoots.add(nonOptionArgs.get(i).toString()); 088 } 089 090 operationOptions.setWatchRoots(watchRoots); 091 } 092 093 return operationOptions; 094 } 095 096 private DaemonAction parseDaemonAction(String actionStr) throws Exception { 097 try { 098 return DaemonAction.valueOf(actionStr.toUpperCase()); 099 } 100 catch (Exception e) { 101 throw new Exception("Invalid syntax, unknown action '" + actionStr + "'"); 102 } 103 } 104 105 @Override 106 public void printResults(OperationResult operationResult) { 107 DaemonOperationResult concreteOperationResult = (DaemonOperationResult) operationResult; 108 109 switch (action) { 110 case LIST: 111 printResultList(concreteOperationResult); 112 return; 113 114 case ADD: 115 printResultAdd(concreteOperationResult); 116 return; 117 118 case REMOVE: 119 printResultRemove(concreteOperationResult); 120 return; 121 122 default: 123 // Nothing. 124 } 125 } 126 127 private void printResultList(DaemonOperationResult operationResult) { 128 List<String[]> tableValues = new ArrayList<String[]>(); 129 tableValues.add(new String[] { "#", "Enabled", "Path" }); 130 131 for (int i=0; i<operationResult.getWatchList().size(); i++) { 132 FolderTO folderTO = operationResult.getWatchList().get(i); 133 134 String number = Integer.toString(i+1); 135 String enabledStr = folderTO.isEnabled() ? "yes" : "no"; 136 137 tableValues.add(new String[] { number, enabledStr, folderTO.getPath() }); 138 } 139 140 CliTableUtil.printTable(out, tableValues, "No managed folders found."); 141 } 142 143 private void printResultAdd(DaemonOperationResult operationResult) { 144 switch (operationResult.getResultCode()) { 145 case OK: 146 out.println("Folder(s) successfully added to daemon config."); 147 out.println("Run 'sy daemon reload' to apply the changes."); 148 out.println(); 149 break; 150 151 case OK_PARTIAL: 152 out.println("Not all folder(s) were added successfully. Please check the following"); 153 out.println("list to see which folders could not be added:"); 154 out.println(); 155 156 printResultList(operationResult); 157 158 break; 159 160 case NOK: 161 out.println("Folder(s) were NOT added, because they might already exists in the daemon configuration."); 162 out.println(); 163 break; 164 165 default: 166 throw new RuntimeException("Invalid result code for this action: " + operationResult.getResultCode()); 167 } 168 } 169 170 private void printResultRemove(DaemonOperationResult operationResult) { 171 switch (operationResult.getResultCode()) { 172 case OK: 173 out.println("Folder(s) successfully removed from the daemon config."); 174 out.println("Run 'sy daemon reload' to apply the changes."); 175 out.println(); 176 break; 177 178 case NOK_PARTIAL: 179 out.println("Not all folder(s) were removed successfully. Please check the following"); 180 out.println("list to see which folders could not be added:"); 181 out.println(); 182 183 printResultList(operationResult); 184 break; 185 186 case NOK: 187 out.println("Folder(s) could not be NOT removed, because they did not exist in the daemon config."); 188 out.println(); 189 break; 190 191 default: 192 throw new RuntimeException("Invalid result code for this action: " + operationResult.getResultCode()); 193 } 194 } 195}