Support shutdown command in JB protocol

This commit is contained in:
Konstantin Bulenkov
2016-02-10 18:15:52 +01:00
parent 978586e677
commit 804e7dc2cb
4 changed files with 117 additions and 20 deletions
@@ -38,6 +38,7 @@ import org.jetbrains.io.BuiltInServer;
import org.jetbrains.io.MessageDecoder;
import java.io.*;
import java.lang.management.ManagementFactory;
import java.net.ConnectException;
import java.net.Socket;
import java.util.Collection;
@@ -45,6 +46,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
/**
* @author mike
@@ -55,6 +57,7 @@ public final class SocketLock {
private static final String PORT_FILE = "port";
private static final String PORT_LOCK_FILE = "port.lock";
private static final String ACTIVATE_COMMAND = "activate ";
private static final String PID_COMMAND = "pid";
private static final String PATHS_EOT_RESPONSE = "---";
private static final String OK_RESPONSE = "ok";
@@ -214,6 +217,9 @@ public final class SocketLock {
String response = in.readUTF();
log("read: response=%s", response);
if (response.equals(OK_RESPONSE)) {
if (isShutdownCommand(args)) {
printPID(portNumber);
}
return ActivateStatus.ACTIVATED;
}
}
@@ -238,6 +244,34 @@ public final class SocketLock {
return ActivateStatus.NO_INSTANCE;
}
private static void printPID(int port) {
try {
Socket socket = new Socket(NetUtils.getLoopbackAddress(), port);
socket.setSoTimeout(1000);
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed") DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(PID_COMMAND);
DataInputStream in = new DataInputStream(socket.getInputStream());
int pid = 0;
while (true) {
try {
String s = in.readUTF();
if (Pattern.matches("[0-9]+@.*", s)) {
pid = Integer.parseInt(s.substring(0, s.indexOf('@')));
System.err.println(pid);
}
}catch (IOException e) {
break;
}
}
}
catch (Exception ignore) {
}
}
private static boolean isShutdownCommand(String[] args) {
return args.length != 0 && Pattern.matches(JetBrainsProtocolHandler.PROTOCOL + "[*]?[a-z0-9A-Z]*/shutdown.*", args[0]);
}
private static String[] checkForJetBrainsProtocolCommand(String[] args) {
final String jbUrl = System.getProperty(JetBrainsProtocolHandler.class.getName());
if (jbUrl != null) {
@@ -298,6 +332,15 @@ public final class SocketLock {
return;
}
if (StringUtil.startsWith(command, PID_COMMAND)) {
ByteBuf buffer = context.alloc().ioBuffer();
ByteBufOutputStream out = new ByteBufOutputStream(buffer);
String name = ManagementFactory.getRuntimeMXBean().getName();
out.writeUTF(name);
out.close();
context.writeAndFlush(buffer);
}
if (StringUtil.startsWith(command, ACTIVATE_COMMAND)) {
List<String> args = StringUtil.split(command.subSequence(ACTIVATE_COMMAND.length(), command.length()).toString(), "\0");
Consumer<List<String>> listener = myActivateListener.get();
@@ -0,0 +1,48 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.application;
import com.intellij.CommonBundle;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.ui.MessageDialogBuilder;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import java.util.Map;
/**
* @author Konstantin Bulenkov
*/
public class JBProtocolShutdownCommand extends JBProtocolCommand {
public JBProtocolShutdownCommand() {
super("shutdown");
}
@Override
public void perform(String target, Map<String, String> parameters) {
if (StringUtil.isEmpty(target)) {
ApplicationManager.getApplication().exit();
} else {
MessageDialogBuilder.YesNo confirmExitDialog = MessageDialogBuilder.yesNo(ApplicationBundle.message("exit.confirm.title"), target)
.yesText(ApplicationBundle.message("command.exit")).noText(
CommonBundle.message("button.cancel"));
if (confirmExitDialog.show() == Messages.YES) {
ApplicationManagerEx.getApplicationEx().exit(true, true);
}
}
}
}
@@ -408,6 +408,7 @@
<ui.suitableFontProvider implementation="com.intellij.ui.SuitableFontProviderImpl"/>
<jbProtocolCommand implementation="com.intellij.openapi.project.impl.JBProtocolOpenProjectCommand"/>
<jbProtocolCommand implementation="com.intellij.openapi.application.JBProtocolShutdownCommand"/>
<intentionAction>
<className>com.intellij.openapi.editor.actions.FlipCommaIntention</className>
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,28 +38,33 @@ public class JetBrainsProtocolHandler {
public static void processJetBrainsLauncherParameters(String url) {
System.setProperty(JetBrainsProtocolHandler.class.getName(), url);
url = url.substring(PROTOCOL.length());
String platformPrefix = url.substring(0, url.indexOf('/'));
url = url.substring(platformPrefix.length() + 1);
String command = url.substring(0, url.indexOf('/'));
url = url.substring(command.length() + 1);
List<String> strings = StringUtil.split(url, "?");
ourMainParameter = strings.get(0);
ourCommand = command;
List<String> urlParts = StringUtil.split(url, "/");
if (urlParts.size() < 2) {
System.err.print("Wrong URL: " + PROTOCOL + url);
return;
}
String platformPrefix = urlParts.get(0);
ourCommand = urlParts.get(1);
if (urlParts.size() > 2) {
url = url.substring(platformPrefix.length() + 1 + ourCommand.length() + 1);
List<String> strings = StringUtil.split(url, "?");
ourMainParameter = strings.get(0);
if (strings.size() > 1) {
List<String> keyValues = StringUtil.split(StringUtil.join(ContainerUtil.subList(strings, 1), "?"), "&");
for (String keyValue : keyValues) {
if (keyValue.contains("=")) {
int ind = keyValue.indexOf('=');
String key = keyValue.substring(0, ind);
String value = keyValue.substring(ind + 1);
if (REQUIRED_PLUGINS_KEY.equals(key)) {
System.setProperty(key, value);
if (strings.size() > 1) {
List<String> keyValues = StringUtil.split(StringUtil.join(ContainerUtil.subList(strings, 1), "?"), "&");
for (String keyValue : keyValues) {
if (keyValue.contains("=")) {
int ind = keyValue.indexOf('=');
String key = keyValue.substring(0, ind);
String value = keyValue.substring(ind + 1);
if (REQUIRED_PLUGINS_KEY.equals(key)) {
System.setProperty(key, value);
} else {
ourParameters.put(key, value);
}
} else {
ourParameters.put(key, value);
ourParameters.put(keyValue, "");
}
} else {
ourParameters.put(keyValue, "");
}
}
}