PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/netbeans-7.3/php.project/src/org/netbeans/modules/php/project/ui/actions/RemoteCommand.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 427 lines | 331 code | 45 blank | 51 comment | 47 complexity | 737283f1998f6f6127d429c775aa608e MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2008 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.php.project.ui.actions;
  43. import java.awt.Color;
  44. import java.io.IOException;
  45. import java.util.ArrayDeque;
  46. import java.util.ArrayList;
  47. import java.util.Arrays;
  48. import java.util.Collection;
  49. import java.util.Collections;
  50. import java.util.Deque;
  51. import java.util.Map;
  52. import java.util.Queue;
  53. import java.util.Set;
  54. import java.util.TreeMap;
  55. import java.util.concurrent.ConcurrentLinkedQueue;
  56. import org.netbeans.api.progress.ProgressHandle;
  57. import org.netbeans.modules.php.project.PhpProject;
  58. import org.netbeans.modules.php.project.PhpVisibilityQuery;
  59. import org.netbeans.modules.php.project.ProjectPropertiesSupport;
  60. import org.netbeans.modules.php.project.connections.RemoteClient;
  61. import org.netbeans.modules.php.project.connections.RemoteClient.Operation;
  62. import org.netbeans.modules.php.project.connections.transfer.TransferFile;
  63. import org.netbeans.modules.php.project.connections.transfer.TransferInfo;
  64. import org.netbeans.modules.php.project.runconfigs.RunConfigRemote;
  65. import org.netbeans.modules.php.project.runconfigs.validation.RunConfigRemoteValidator;
  66. import org.netbeans.modules.php.project.ui.customizer.PhpProjectProperties;
  67. import org.netbeans.modules.php.project.util.PhpProjectUtils;
  68. import org.openide.DialogDisplayer;
  69. import org.openide.NotifyDescriptor;
  70. import org.openide.filesystems.FileObject;
  71. import org.openide.filesystems.FileUtil;
  72. import org.openide.util.Exceptions;
  73. import org.openide.util.Lookup;
  74. import org.openide.util.NbBundle;
  75. import org.openide.util.RequestProcessor;
  76. import org.openide.windows.IOColorLines;
  77. import org.openide.windows.IOProvider;
  78. import org.openide.windows.InputOutput;
  79. import org.openide.windows.OutputWriter;
  80. /**
  81. * @author Radek Matous
  82. */
  83. public abstract class RemoteCommand extends Command {
  84. private static final char SEP_CHAR = '='; // NOI18N
  85. private static final int MAX_TYPE_SIZE = getFileTypeLabelMaxSize() + 2;
  86. private static final Color COLOR_SUCCESS = Color.GREEN.darker().darker();
  87. private static final Color COLOR_IGNORE = Color.ORANGE.darker();
  88. private static final RequestProcessor RP = new RequestProcessor("Remote connection", 1); // NOI18N
  89. private static final Queue<Runnable> RUNNABLES = new ConcurrentLinkedQueue<Runnable>();
  90. private static final RequestProcessor.Task TASK = RP.create(new Runnable() {
  91. @Override
  92. public void run() {
  93. Runnable toRun = RUNNABLES.poll();
  94. while (toRun != null) {
  95. toRun.run();
  96. toRun = RUNNABLES.poll();
  97. }
  98. }
  99. }, true);
  100. public RemoteCommand(PhpProject project) {
  101. super(project);
  102. }
  103. @Override
  104. public boolean isFileSensitive() {
  105. return true;
  106. }
  107. @Override
  108. public final void invokeActionInternal(Lookup context) {
  109. assert getConfigAction().getClass().getSimpleName().equals("ConfigActionRemote") : "Remote config action expected but found: " + getConfigAction().getClass().getSimpleName();
  110. if (RunConfigRemoteValidator.validateRemoteTransfer(RunConfigRemote.forProject(getProject())) != null) {
  111. PhpProjectUtils.openCustomizerRun(getProject());
  112. return;
  113. }
  114. RUNNABLES.add(getContextRunnable(context));
  115. TASK.schedule(0);
  116. }
  117. @Override
  118. public final boolean isActionEnabledInternal(Lookup context) {
  119. // WARNING context can be null, see RunCommand.invokeAction()
  120. return isRemoteConfigSelected() && TASK.isFinished();
  121. }
  122. protected abstract Runnable getContextRunnable(Lookup context);
  123. @Override
  124. public final boolean asyncCallRequired() {
  125. return false;
  126. }
  127. public static InputOutput getRemoteLog(String displayName) {
  128. return getRemoteLog(displayName, true);
  129. }
  130. public static InputOutput getRemoteLog(String displayName, boolean select) {
  131. InputOutput io = IOProvider.getDefault().getIO(NbBundle.getMessage(Command.class, "LBL_RemoteLog", displayName), false);
  132. if (select) {
  133. io.select();
  134. }
  135. try {
  136. io.getOut().reset();
  137. } catch (IOException ex) {
  138. Exceptions.printStackTrace(ex);
  139. }
  140. return io;
  141. }
  142. protected RemoteClient getRemoteClient(InputOutput io) {
  143. RunConfigRemote runConfig = RunConfigRemote.forProject(getProject());
  144. return new RemoteClient(runConfig.getRemoteConfiguration(), new RemoteClient.AdvancedProperties()
  145. .setInputOutput(io)
  146. .setAdditionalInitialSubdirectory(runConfig.getUploadDirectory())
  147. .setPreservePermissions(runConfig.arePermissionsPreserved())
  148. .setUploadDirectly(runConfig.getUploadDirectly())
  149. .setPhpVisibilityQuery(PhpVisibilityQuery.forProject(getProject())));
  150. }
  151. protected boolean isRemoteConfigSelected() {
  152. PhpProjectProperties.RunAsType runAs = ProjectPropertiesSupport.getRunAs(getProject());
  153. return PhpProjectProperties.RunAsType.REMOTE.equals(runAs);
  154. }
  155. protected static void processTransferInfo(TransferInfo transferInfo, InputOutput io) {
  156. processTransferInfo(transferInfo, io, NbBundle.getMessage(RemoteCommand.class, "LBL_RemoteSummary"));
  157. }
  158. protected static void processTransferInfo(TransferInfo transferInfo, InputOutput io, String title) {
  159. OutputWriter out = io.getOut();
  160. OutputWriter err = io.getErr();
  161. out.println();
  162. out.println(title);
  163. StringBuilder sep = new StringBuilder(20);
  164. for (int i = 0; i < sep.capacity(); i++) {
  165. sep.append(SEP_CHAR);
  166. }
  167. out.println(sep.toString());
  168. int maxRelativePath = getRelativePathMaxSize(transferInfo);
  169. long size = 0;
  170. int files = 0;
  171. if (transferInfo.hasAnyTransfered()) {
  172. printSuccess(io, NbBundle.getMessage(RemoteCommand.class, "LBL_RemoteSucceeded"));
  173. ArrayList<TransferFile> sorted = new ArrayList<TransferFile>(transferInfo.getTransfered());
  174. Collections.sort(sorted, TransferFile.TRANSFER_FILE_COMPARATOR);
  175. for (TransferFile file : sorted) {
  176. printSuccess(io, maxRelativePath, file);
  177. if (file.isFile()) {
  178. size += file.getSize();
  179. files++;
  180. }
  181. }
  182. }
  183. if (transferInfo.hasAnyFailed()) {
  184. err.println(NbBundle.getMessage(RemoteCommand.class, "LBL_RemoteFailed"));
  185. Map<TransferFile, String> sorted = new TreeMap<TransferFile, String>(TransferFile.TRANSFER_FILE_COMPARATOR);
  186. sorted.putAll(transferInfo.getFailed());
  187. for (Map.Entry<TransferFile, String> entry : sorted.entrySet()) {
  188. printError(err, maxRelativePath, entry.getKey(), entry.getValue());
  189. }
  190. }
  191. if (transferInfo.hasAnyPartiallyFailed()) {
  192. err.println(NbBundle.getMessage(RemoteCommand.class, "LBL_RemotePartiallyFailed"));
  193. Map<TransferFile, String> sorted = new TreeMap<TransferFile, String>(TransferFile.TRANSFER_FILE_COMPARATOR);
  194. sorted.putAll(transferInfo.getPartiallyFailed());
  195. for (Map.Entry<TransferFile, String> entry : sorted.entrySet()) {
  196. printError(err, maxRelativePath, entry.getKey(), entry.getValue());
  197. }
  198. }
  199. if (transferInfo.hasAnyIgnored()) {
  200. printIgnore(io, NbBundle.getMessage(RemoteCommand.class, "LBL_RemoteIgnored"));
  201. Map<TransferFile, String> sorted = new TreeMap<TransferFile, String>(TransferFile.TRANSFER_FILE_COMPARATOR);
  202. sorted.putAll(transferInfo.getIgnored());
  203. for (Map.Entry<TransferFile, String> entry : sorted.entrySet()) {
  204. printIgnore(io, maxRelativePath, entry.getKey(), entry.getValue());
  205. }
  206. }
  207. // summary
  208. long runtime = transferInfo.getRuntime();
  209. String timeUnit = NbBundle.getMessage(RemoteCommand.class, "LBL_TimeUnitMilisecond");
  210. if (runtime > 1000) {
  211. runtime /= 1000;
  212. timeUnit = NbBundle.getMessage(RemoteCommand.class, "LBL_TimeUnitSecond");
  213. }
  214. double s = size / 1024.0;
  215. String sizeUnit = NbBundle.getMessage(RemoteCommand.class, "LBL_SizeUnitKilobyte");
  216. if (s > 1024) {
  217. s /= 1024.0;
  218. sizeUnit = NbBundle.getMessage(RemoteCommand.class, "LBL_SizeUnitMegabyte");
  219. }
  220. Object[] params = new Object[] {
  221. runtime,
  222. timeUnit,
  223. files,
  224. s,
  225. sizeUnit,
  226. };
  227. out.println(NbBundle.getMessage(RemoteCommand.class, "MSG_RemoteRuntimeAndSize", params));
  228. }
  229. private static void print(InputOutput io, String message, Color color) {
  230. try {
  231. IOColorLines.println(io, message, color);
  232. } catch (IOException ex) {
  233. Exceptions.printStackTrace(ex);
  234. }
  235. }
  236. private static void printSuccess(InputOutput io, String message) {
  237. print(io, message.trim(), COLOR_SUCCESS);
  238. }
  239. private static void printSuccess(InputOutput io, int maxRelativePath, TransferFile file) {
  240. String message = String.format("%-" + MAX_TYPE_SIZE + "s %-" + maxRelativePath + "s", getFileTypeLabel(file), file.getRemotePath());
  241. printSuccess(io, message);
  242. }
  243. private static void printError(OutputWriter writer, int maxRelativePath, TransferFile file, String reason) {
  244. String msg = String.format("%-" + MAX_TYPE_SIZE + "s %-" + maxRelativePath + "s %s", getFileTypeLabel(file), file.getRemotePath(), reason);
  245. writer.println(msg);
  246. }
  247. private static void printIgnore(InputOutput io, String message) {
  248. print(io, message, COLOR_IGNORE);
  249. }
  250. private static void printIgnore(InputOutput io, int maxRelativePath, TransferFile file, String reason) {
  251. String msg = String.format("%-" + MAX_TYPE_SIZE + "s %-" + maxRelativePath + "s %s", getFileTypeLabel(file), file.getRemotePath(), reason);
  252. printIgnore(io, msg);
  253. }
  254. private static String getFileTypeLabel(TransferFile file) {
  255. String type = null;
  256. if (file.isDirectory()) {
  257. type = "LBL_TypeDirectory"; // NOI18N
  258. } else if (file.isFile()) {
  259. type = "LBL_TypeFile"; // NOI18N
  260. } else if (file.isLink()) {
  261. type = "LBL_TypeLink"; // NOI18N
  262. } else {
  263. type = "LBL_TypeUnknown"; // NOI18N
  264. }
  265. return NbBundle.getMessage(RemoteCommand.class, type);
  266. }
  267. private static int getFileTypeLabelMaxSize() {
  268. int max = 0;
  269. for (String label : Arrays.asList("LBL_TypeDirectory", "LBL_TypeFile", "LBL_TypeLink", "LBL_TypeUnknown")) { // NOI18N
  270. int length = NbBundle.getMessage(RemoteCommand.class, label).length();
  271. if (max < length) {
  272. max = length;
  273. }
  274. }
  275. return max;
  276. }
  277. private static int getRelativePathMaxSize(TransferInfo transferInfo) {
  278. int max = getRelativePathMaxSize(transferInfo.getTransfered());
  279. int size = getRelativePathMaxSize(transferInfo.getFailed().keySet());
  280. if (size > max) {
  281. max = size;
  282. }
  283. size = getRelativePathMaxSize(transferInfo.getPartiallyFailed().keySet());
  284. if (size > max) {
  285. max = size;
  286. }
  287. size = getRelativePathMaxSize(transferInfo.getIgnored().keySet());
  288. if (size > max) {
  289. max = size;
  290. }
  291. return max + 2;
  292. }
  293. private static int getRelativePathMaxSize(Collection<TransferFile> files) {
  294. int max = 0;
  295. for (TransferFile file : files) {
  296. int length = file.getRemotePath().length();
  297. if (length > max) {
  298. max = length;
  299. }
  300. }
  301. return max;
  302. }
  303. // # 161620
  304. protected final boolean sourcesFilesOnly(FileObject sources, FileObject[] selectedFiles) {
  305. for (FileObject file : selectedFiles) {
  306. if (!FileUtil.isParentOf(sources, file) && !sources.equals(file)) {
  307. DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
  308. NbBundle.getMessage(RemoteCommand.class, "MSG_TransferSourcesOnly"),
  309. NotifyDescriptor.ERROR_MESSAGE));
  310. return false;
  311. }
  312. }
  313. return true;
  314. }
  315. //~ Inner classes
  316. /**
  317. * Default operation monitor for file upload and download.
  318. */
  319. public static final class DefaultOperationMonitor implements RemoteClient.OperationMonitor {
  320. private final Deque<Operation> operations = new ArrayDeque<Operation>();
  321. private final ProgressHandle progressHandle;
  322. private int workUnits = 0;
  323. private int workUnit = 0;
  324. public DefaultOperationMonitor(ProgressHandle progressHandle, Set<TransferFile> forFiles) {
  325. if (progressHandle == null) {
  326. throw new IllegalStateException("Progress handle must be set");
  327. }
  328. this.progressHandle = progressHandle;
  329. workUnits = getWorkUnits(forFiles);
  330. }
  331. @Override
  332. public void operationStart(Operation operation, Collection<TransferFile> forFiles) {
  333. if (operations.isEmpty()) {
  334. progressHandle.start(workUnits);
  335. }
  336. operations.offerFirst(operation);
  337. if (operation == Operation.LIST) {
  338. progressHandle.progress(NbBundle.getMessage(RemoteCommand.class, "LBL_ListingFiles", forFiles.iterator().next().getName()));
  339. progressHandle.switchToIndeterminate();
  340. }
  341. }
  342. @Override
  343. public void operationProcess(Operation operation, TransferFile forFile) {
  344. long size = forFile.getSize();
  345. switch (operation) {
  346. case LIST:
  347. if (size > 0) {
  348. workUnits += size / 1024;
  349. }
  350. break;
  351. case UPLOAD:
  352. case DOWNLOAD:
  353. if (size > 0) {
  354. String processMessageKey = operation == Operation.DOWNLOAD ? "LBL_Downloading" : "LBL_Uploading"; // NOI18N
  355. progressHandle.progress(NbBundle.getMessage(DefaultOperationMonitor.class, processMessageKey, forFile.getName()), workUnit);
  356. workUnit += size / 1024;
  357. }
  358. break;
  359. default:
  360. throw new IllegalStateException("Unsupported operation: " + operation);
  361. }
  362. }
  363. @Override
  364. public void operationFinish(Operation operation, Collection<TransferFile> forFiles) {
  365. operations.pollFirst();
  366. if (operation == Operation.LIST) {
  367. progressHandle.switchToDeterminate(workUnits);
  368. progressHandle.progress(workUnit);
  369. }
  370. if (operations.isEmpty()) {
  371. progressHandle.finish();
  372. }
  373. }
  374. private int getWorkUnits(Set<TransferFile> forFiles) {
  375. int size = 0;
  376. for (TransferFile file : forFiles) {
  377. size += file.getSize();
  378. }
  379. return size / 1024;
  380. }
  381. }
  382. }