package krasa.visualvm.runner;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.impl.DebuggerManagerImpl;
import com.intellij.debugger.impl.GenericDebuggerRunner;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.ConfigurationInfoProvider;
import com.intellij.execution.configurations.JavaCommandLine;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.ModuleRunProfile;
import com.intellij.execution.configurations.RemoteConnection;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.remote.RemoteConfiguration;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import krasa.visualvm.*;
import krasa.visualvm.executor.DebugVisualVMExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DebugVisualVMRunner extends GenericDebuggerRunner {
private static final Logger log = Logger.getInstance(DebugVisualVMRunner.class.getName());
@NotNull
public String getRunnerId() {
return DebugVisualVMExecutor.EXECUTOR_ID;
}
@Override
public void execute(@NotNull final ExecutionEnvironment environment)
throws ExecutionException {
LogHelper.print("#execute", this);
final VisualVMGenericDebuggerRunnerSettings debuggerSettings = ((VisualVMGenericDebuggerRunnerSettings) environment.getRunnerSettings());
debuggerSettings.generateId();
new VisualVMContext(debuggerSettings).save();
boolean b = MyConfigurable.openSettingsIfNotConfigured(environment.getProject());
if (!b) {
return;
}
super.execute(environment);
}
public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
return executorId.equals(DebugVisualVMExecutor.EXECUTOR_ID) && profile instanceof ModuleRunProfile
&& !(profile instanceof RemoteConfiguration);
}
@Override
public VisualVMGenericDebuggerRunnerSettings createConfigurationData(ConfigurationInfoProvider settingsProvider) {
return new VisualVMGenericDebuggerRunnerSettings();
}
@Override
public void patch(JavaParameters javaParameters, RunnerSettings settings, RunProfile runProfile, boolean beforeExecution)
throws ExecutionException {
LogHelper.print("#patch", this);
doPatch(javaParameters, settings);
runCustomPatchers(javaParameters, Executor.EXECUTOR_EXTENSION_NAME.findExtension(DefaultDebugExecutor.class), runProfile);
}
/*is called for tomcat, but not normal application*/
private RemoteConnection doPatch(final JavaParameters javaParameters, final RunnerSettings settings) throws ExecutionException {
final VisualVMGenericDebuggerRunnerSettings debuggerSettings = ((VisualVMGenericDebuggerRunnerSettings) settings);
if (StringUtil.isEmpty(debuggerSettings.getDebugPort())) {
debuggerSettings.setDebugPort(DebuggerUtils.getInstance().findAvailableDebugAddress(debuggerSettings.getTransport() == DebuggerSettings.SOCKET_TRANSPORT));
}
LogHelper.print("#doPatch -Dvisualvm.id=" + debuggerSettings.getVisualVMId(), this);
javaParameters.getVMParametersList().add("-Dvisualvm.id=" + debuggerSettings.getVisualVMId());
return DebuggerManagerImpl.createDebugParameters(javaParameters, debuggerSettings, false);
}
@Nullable
@Override
protected RunContentDescriptor createContentDescriptor(@NotNull RunProfileState state,
@NotNull ExecutionEnvironment environment) throws ExecutionException {
LogHelper.print("#createContentDescriptor", this);
addVisualVMIdToJavaParameter(environment, state);
return super.createContentDescriptor(state, environment);
}
/*is called for normal application*/
private void addVisualVMIdToJavaParameter(ExecutionEnvironment executionEnvironment, RunProfileState runProfileState) throws ExecutionException {
final VisualVMGenericDebuggerRunnerSettings debuggerSettings = ((VisualVMGenericDebuggerRunnerSettings) executionEnvironment.getRunnerSettings());
if (runProfileState instanceof JavaCommandLine) {
final JavaParameters parameters = ((JavaCommandLine) runProfileState).getJavaParameters();
LogHelper.print("#createContentDescriptor -Dvisualvm.id=" + debuggerSettings.getVisualVMId(), this);
parameters.getVMParametersList().add("-Dvisualvm.id=" + debuggerSettings.getVisualVMId());
}
}
@Nullable
@Override
protected RunContentDescriptor attachVirtualMachine(RunProfileState state, @NotNull ExecutionEnvironment env,
RemoteConnection connection, boolean pollConnection) throws ExecutionException {
RunContentDescriptor runContentDescriptor = super.attachVirtualMachine(state, env, connection, pollConnection);
LogHelper.print("#attachVirtualMachine", this);
runVisualVM(env, state);
return runContentDescriptor;
}
private void runVisualVM(ExecutionEnvironment env, RunProfileState state) throws ExecutionException {
final VisualVMGenericDebuggerRunnerSettings debuggerSettings = ((VisualVMGenericDebuggerRunnerSettings) env.getRunnerSettings());
// tomcat uses PatchedLocalState
if (state.getClass().getSimpleName().equals(Hacks.BUNDLED_SERVERS_RUN_PROFILE_STATE)) {
LogHelper.print("#runVisualVM ExecutionEnvironment", this);
new Thread() {
@Override
public void run() {
LogHelper.print("#Thread run", this);
try {
Thread.sleep(ApplicationSettingsComponent.getInstance().getState().getDelayForVisualVMStartAsLong());
VisualVMHelper.startVisualVM(debuggerSettings, DebugVisualVMRunner.this);
} catch (Exception e) {
log.error(e);
}
}
}.start();
} else {
VisualVMHelper.startVisualVM(debuggerSettings, this);
}
}
}