[java] capability-aware process proxy API

This commit is contained in:
Roman Shevchenko
2016-10-27 12:03:47 +02:00
parent ca19edad18
commit a558919cc8
5 changed files with 56 additions and 58 deletions
@@ -149,54 +149,61 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
contentBuilder.addAction(new SoftExitAction(executionResult.getProcessHandler()));
}
private abstract static class LauncherBasedAction extends AnAction {
private abstract static class ProxyBasedAction extends AnAction {
protected final ProcessHandler myProcessHandler;
protected LauncherBasedAction(String text, String description, Icon icon, ProcessHandler processHandler) {
protected ProxyBasedAction(String text, String description, Icon icon, ProcessHandler processHandler) {
super(text, description, icon);
myProcessHandler = processHandler;
}
@Override
public void update(@NotNull final AnActionEvent event) {
final Presentation presentation = event.getPresentation();
if (!isVisible()) {
presentation.setVisible(false);
presentation.setEnabled(false);
return;
public final void update(@NotNull AnActionEvent event) {
ProcessProxy proxy = ProcessProxyFactory.getInstance().getAttachedProxy(myProcessHandler);
boolean available = proxy != null && available(proxy);
Presentation presentation = event.getPresentation();
if (!available) {
presentation.setEnabledAndVisible(false);
}
else {
presentation.setVisible(true);
presentation.setEnabled(!myProcessHandler.isProcessTerminated());
}
presentation.setVisible(true);
presentation.setEnabled(!myProcessHandler.isProcessTerminated());
}
protected boolean isVisible() {
return ProcessProxyFactory.getInstance().getAttachedProxy(myProcessHandler) != null;
@Override
public final void actionPerformed(@NotNull AnActionEvent e) {
ProcessProxy proxy = ProcessProxyFactory.getInstance().getAttachedProxy(myProcessHandler);
if (proxy != null) {
perform(e, proxy);
}
}
protected abstract boolean available(ProcessProxy proxy);
protected abstract void perform(AnActionEvent e, ProcessProxy proxy);
}
protected static class ControlBreakAction extends LauncherBasedAction {
protected static class ControlBreakAction extends ProxyBasedAction {
public ControlBreakAction(final ProcessHandler processHandler) {
super(ExecutionBundle.message("run.configuration.dump.threads.action.name"), null, AllIcons.Actions.Dump, processHandler);
setShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_CANCEL, InputEvent.CTRL_DOWN_MASK)));
}
@Override
protected boolean isVisible() {
return super.isVisible() && ProcessProxyFactory.getInstance().isBreakGenLibraryAvailable();
protected boolean available(ProcessProxy proxy) {
return proxy.canSendBreak();
}
@Override
public void actionPerformed(@NotNull final AnActionEvent e) {
ProcessProxy proxy = ProcessProxyFactory.getInstance().getAttachedProxy(myProcessHandler);
if (proxy != null) {
boolean wise = Boolean.getBoolean(ourWiseThreadDumpProperty);
WiseDumpThreadsListener wiseListener = wise ? new WiseDumpThreadsListener(e.getProject(), myProcessHandler) : null;
protected void perform(AnActionEvent e, ProcessProxy proxy) {
boolean wise = Boolean.getBoolean(ourWiseThreadDumpProperty);
WiseDumpThreadsListener wiseListener = wise ? new WiseDumpThreadsListener(e.getProject(), myProcessHandler) : null;
proxy.sendBreak();
proxy.sendBreak();
if (wiseListener != null) {
wiseListener.after();
}
if (wiseListener != null) {
wiseListener.after();
}
}
}
@@ -206,10 +213,9 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
private final ProcessHandler myProcessHandler;
private final CapturingProcessAdapter myListener;
public WiseDumpThreadsListener(final Project project, final ProcessHandler processHandler) {
public WiseDumpThreadsListener(Project project, ProcessHandler processHandler) {
myProject = project;
myProcessHandler = processHandler;
myListener = new CapturingProcessAdapter();
myProcessHandler.addProcessListener(myListener);
}
@@ -248,17 +254,19 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
}
}
protected static class SoftExitAction extends LauncherBasedAction {
protected static class SoftExitAction extends ProxyBasedAction {
public SoftExitAction(final ProcessHandler processHandler) {
super(ExecutionBundle.message("run.configuration.exit.action.name"), null, AllIcons.Actions.Exit, processHandler);
}
@Override
public void actionPerformed(@NotNull final AnActionEvent e) {
ProcessProxy proxy = ProcessProxyFactory.getInstance().getAttachedProxy(myProcessHandler);
if (proxy != null) {
proxy.sendStop();
}
protected boolean available(ProcessProxy proxy) {
return proxy.canSendStop();
}
@Override
protected void perform(AnActionEvent e, ProcessProxy proxy) {
proxy.sendStop();
}
}
}
@@ -22,9 +22,6 @@ import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
import com.intellij.openapi.util.SystemInfo;
import java.io.File;
public class ProcessProxyFactoryImpl extends ProcessProxyFactory {
private static final String DONT_USE_LAUNCHER_PROPERTY = "idea.no.launcher";
@@ -57,21 +54,6 @@ public class ProcessProxyFactoryImpl extends ProcessProxyFactory {
return processHandler != null ? processHandler.getUserData(ProcessProxyImpl.KEY) : null;
}
@Override
public boolean isBreakGenLibraryAvailable() {
String libName;
if (SystemInfo.isWindows) {
libName = "breakgen.dll";
}
else if (SystemInfo.isMac) {
libName = "libbreakgen.jnilib";
}
else {
libName = "libbreakgen.so";
}
return new File(PathManager.getBinPath(), libName).exists();
}
private static boolean useLauncher(JavaParameters parameters) {
return !Boolean.getBoolean(DONT_USE_LAUNCHER_PROPERTY) && parameters.getModuleName() == null;
}
@@ -16,13 +16,12 @@
package com.intellij.execution.runners;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.SystemInfo;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
@@ -95,6 +94,15 @@ class ProcessProxyImpl implements ProcessProxy {
myWriter.flush();
}
@Override
public boolean canSendBreak() {
String libName = null;
if (SystemInfo.isWindows) libName = "breakgen.dll";
else if (SystemInfo.isMac) libName = "libbreakgen.jnilib";
else if (SystemInfo.isLinux) libName = "libbreakgen.so";
return libName != null && new File(PathManager.getBinPath(), libName).exists();
}
@Override
public void sendBreak() {
writeLine("BREAK");
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 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.
@@ -22,8 +22,6 @@ import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.annotations.Nullable;
public abstract class ProcessProxyFactory {
public abstract boolean isBreakGenLibraryAvailable();
public static ProcessProxyFactory getInstance() {
return ServiceManager.getService(ProcessProxyFactory.class);
}
@@ -23,8 +23,10 @@ public interface ProcessProxy {
void attach(@NotNull ProcessHandler processHandler);
void sendBreak();
default boolean canSendBreak() { return true; }
default boolean canSendStop() { return true; }
void sendBreak();
void sendStop();
default void destroy() { }