/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgPromptCommandExecutor.java

https://github.com/JetBrains/intellij-community · Java · 122 lines · 106 code · 12 blank · 4 comment · 12 complexity · 0f819a819775151c5542ffbe0044645f MD5 · raw file

  1. // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
  2. package org.zmlx.hg4idea.execution;
  3. import com.intellij.openapi.project.Project;
  4. import com.intellij.openapi.ui.Messages;
  5. import com.intellij.openapi.vfs.VirtualFile;
  6. import org.jetbrains.annotations.NotNull;
  7. import org.jetbrains.annotations.Nullable;
  8. import org.zmlx.hg4idea.HgBundle;
  9. import java.awt.*;
  10. import java.io.DataInputStream;
  11. import java.io.DataOutputStream;
  12. import java.io.IOException;
  13. import java.lang.reflect.InvocationTargetException;
  14. import java.net.Socket;
  15. import java.nio.charset.StandardCharsets;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. public class HgPromptCommandExecutor extends HgCommandExecutor {
  19. public HgPromptCommandExecutor(@NotNull Project project) {
  20. super(project);
  21. }
  22. @Override
  23. @Nullable
  24. public HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo,
  25. @NotNull final String operation,
  26. @Nullable final List<String> arguments) {
  27. SocketServer promptServer = new SocketServer(new PromptReceiver(new HgDeleteModifyPromptHandler()));
  28. try {
  29. int promptPort = promptServer.start();
  30. return super.executeInCurrentThread(repo, operation, prepareArguments(arguments, promptPort));
  31. }
  32. catch (IOException e) {
  33. showError(e);
  34. LOG.info("IOException during preparing command", e);
  35. return null;
  36. }
  37. finally {
  38. promptServer.stop();
  39. }
  40. }
  41. private List<String> prepareArguments(List<String> arguments, int port) {
  42. List<String> cmdArguments = new ArrayList<>();
  43. cmdArguments.add("--config");
  44. cmdArguments.add("extensions.hg4ideapromptextension=" + myVcs.getPromptHooksExtensionFile().getAbsolutePath());
  45. cmdArguments.add("--config");
  46. cmdArguments.add("hg4ideaprompt.port=" + port);
  47. if (arguments != null && arguments.size() != 0) {
  48. cmdArguments.addAll(arguments);
  49. }
  50. return cmdArguments;
  51. }
  52. private static class PromptReceiver extends SocketServer.Protocol {
  53. @Nullable HgPromptHandler myHandler;
  54. PromptReceiver(@Nullable HgPromptHandler handler) {
  55. myHandler = handler;
  56. }
  57. @Override
  58. public boolean handleConnection(Socket socket) throws IOException {
  59. //noinspection IOResourceOpenedButNotSafelyClosed
  60. DataInputStream dataInput = new DataInputStream(socket.getInputStream());
  61. DataOutputStream out = new DataOutputStream(socket.getOutputStream());
  62. final String message = new String(readDataBlock(dataInput), StandardCharsets.UTF_8); //NON-NLS
  63. int numOfChoices = dataInput.readInt();
  64. final HgPromptChoice[] choices = new HgPromptChoice[numOfChoices];
  65. for (int i = 0; i < numOfChoices; i++) {
  66. String choice = new String(readDataBlock(dataInput), StandardCharsets.UTF_8);
  67. choices[i] = new HgPromptChoice(i, choice);
  68. }
  69. int defaultChoiceInt = dataInput.readInt();
  70. final HgPromptChoice defaultChoice = choices[defaultChoiceInt];
  71. if (myHandler != null && myHandler.shouldHandle(message)) {
  72. int chosen = myHandler.promptUser(message, choices, defaultChoice).getChosenIndex();
  73. sendChoiceToHg(out, chosen);
  74. return true;
  75. }
  76. final int[] index = new int[]{-1};
  77. try {
  78. EventQueue.invokeAndWait(() -> {
  79. String[] choicePresentationArray = new String[choices.length];
  80. for (int i = 0; i < choices.length; ++i) {
  81. choicePresentationArray[i] = choices[i].toString();
  82. }
  83. index[0] = Messages
  84. .showDialog(message, HgBundle.message("hg4idea.prompt.message"),
  85. choicePresentationArray,
  86. defaultChoice.getChosenIndex(), Messages.getQuestionIcon());
  87. });
  88. int chosen = index[0];
  89. sendChoiceToHg(out, chosen);
  90. return true;
  91. }
  92. catch (InterruptedException e) {
  93. //do nothing
  94. return true;
  95. }
  96. catch (InvocationTargetException e) {
  97. //shouldn't happen
  98. throw new RuntimeException(e);
  99. }
  100. }
  101. private static void sendChoiceToHg(@NotNull DataOutputStream outStream, int choice) throws IOException {
  102. if (choice == HgPromptChoice.CLOSED_OPTION) {
  103. outStream.writeInt(-1);
  104. }
  105. else {
  106. outStream.writeInt(choice);
  107. }
  108. }
  109. }
  110. }