2 * Copyright 2000-2016 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.debugger.impl;
18 import com.intellij.debugger.DebugEnvironment;
19 import com.intellij.debugger.DebuggerManagerEx;
20 import com.intellij.debugger.DefaultDebugEnvironment;
21 import com.intellij.debugger.engine.DebugProcessImpl;
22 import com.intellij.debugger.engine.DebuggerUtils;
23 import com.intellij.debugger.engine.JavaDebugProcess;
24 import com.intellij.debugger.settings.DebuggerSettings;
25 import com.intellij.execution.DefaultExecutionResult;
26 import com.intellij.execution.ExecutionException;
27 import com.intellij.execution.ExecutionResult;
28 import com.intellij.execution.Executor;
29 import com.intellij.execution.configurations.*;
30 import com.intellij.execution.executors.DefaultDebugExecutor;
31 import com.intellij.execution.runners.ExecutionEnvironment;
32 import com.intellij.execution.runners.JavaPatchableProgramRunner;
33 import com.intellij.execution.ui.RunContentDescriptor;
34 import com.intellij.openapi.fileEditor.FileDocumentManager;
35 import com.intellij.openapi.options.SettingsEditor;
36 import com.intellij.openapi.util.text.StringUtil;
37 import com.intellij.xdebugger.XDebugProcess;
38 import com.intellij.xdebugger.XDebugProcessStarter;
39 import com.intellij.xdebugger.XDebugSession;
40 import com.intellij.xdebugger.XDebuggerManager;
41 import com.intellij.xdebugger.impl.XDebugSessionImpl;
42 import org.jetbrains.annotations.NotNull;
43 import org.jetbrains.annotations.Nullable;
45 public class GenericDebuggerRunner extends JavaPatchableProgramRunner<GenericDebuggerRunnerSettings> {
47 public boolean canRun(@NotNull final String executorId, @NotNull final RunProfile profile) {
48 return executorId.equals(DefaultDebugExecutor.EXECUTOR_ID) && profile instanceof ModuleRunProfile
49 && !(profile instanceof RunConfigurationWithSuppressedDefaultDebugAction);
54 public String getRunnerId() {
55 return DebuggingRunnerData.DEBUGGER_RUNNER_ID;
59 protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment env) throws ExecutionException {
60 FileDocumentManager.getInstance().saveAllDocuments();
61 return createContentDescriptor(state, env);
65 protected RunContentDescriptor createContentDescriptor(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException {
66 if (state instanceof JavaCommandLine) {
67 final JavaParameters parameters = ((JavaCommandLine)state).getJavaParameters();
68 runCustomPatchers(parameters, environment.getExecutor(), environment.getRunProfile());
69 RemoteConnection connection = DebuggerManagerImpl.createDebugParameters(parameters, true, DebuggerSettings.getInstance().DEBUGGER_TRANSPORT, "", false);
70 return attachVirtualMachine(state, environment, connection, true);
72 if (state instanceof PatchedRunnableState) {
73 final RemoteConnection connection = doPatch(new JavaParameters(), environment.getRunnerSettings());
74 return attachVirtualMachine(state, environment, connection, true);
76 if (state instanceof RemoteState) {
77 final RemoteConnection connection = createRemoteDebugConnection((RemoteState)state, environment.getRunnerSettings());
78 return attachVirtualMachine(state, environment, connection, false);
85 protected RunContentDescriptor attachVirtualMachine(RunProfileState state,
86 @NotNull ExecutionEnvironment env,
87 RemoteConnection connection,
88 boolean pollConnection) throws ExecutionException {
89 DebugEnvironment environment = new DefaultDebugEnvironment(env, state, connection, pollConnection);
90 final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(env.getProject()).attachVirtualMachine(environment);
91 if (debuggerSession == null) {
95 final DebugProcessImpl debugProcess = debuggerSession.getProcess();
97 return XDebuggerManager.getInstance(env.getProject()).startSession(env, new XDebugProcessStarter() {
100 public XDebugProcess start(@NotNull XDebugSession session) {
101 XDebugSessionImpl sessionImpl = (XDebugSessionImpl)session;
102 ExecutionResult executionResult = debugProcess.getExecutionResult();
103 sessionImpl.addExtraActions(executionResult.getActions());
104 if (executionResult instanceof DefaultExecutionResult) {
105 sessionImpl.addRestartActions(((DefaultExecutionResult)executionResult).getRestartActions());
106 sessionImpl.addExtraStopActions(((DefaultExecutionResult)executionResult).getAdditionalStopActions());
108 return JavaDebugProcess.create(session, debuggerSession);
110 }).getRunContentDescriptor();
113 private static RemoteConnection createRemoteDebugConnection(RemoteState connection, final RunnerSettings settings) {
114 final RemoteConnection remoteConnection = connection.getRemoteConnection();
116 GenericDebuggerRunnerSettings debuggerRunnerSettings = (GenericDebuggerRunnerSettings)settings;
118 if (debuggerRunnerSettings != null) {
119 remoteConnection.setUseSockets(debuggerRunnerSettings.getTransport() == DebuggerSettings.SOCKET_TRANSPORT);
120 remoteConnection.setAddress(debuggerRunnerSettings.getDebugPort());
123 return remoteConnection;
127 public GenericDebuggerRunnerSettings createConfigurationData(ConfigurationInfoProvider settingsProvider) {
128 return new GenericDebuggerRunnerSettings();
132 public void patch(JavaParameters javaParameters, RunnerSettings settings, RunProfile runProfile, final boolean beforeExecution) throws ExecutionException {
133 doPatch(javaParameters, settings);
134 runCustomPatchers(javaParameters, Executor.EXECUTOR_EXTENSION_NAME.findExtension(DefaultDebugExecutor.class), runProfile);
137 private static RemoteConnection doPatch(final JavaParameters javaParameters, final RunnerSettings settings) throws ExecutionException {
138 final GenericDebuggerRunnerSettings debuggerSettings = ((GenericDebuggerRunnerSettings)settings);
139 if (StringUtil.isEmpty(debuggerSettings.getDebugPort())) {
140 debuggerSettings.setDebugPort(DebuggerUtils.getInstance().findAvailableDebugAddress(debuggerSettings.getTransport() == DebuggerSettings.SOCKET_TRANSPORT));
142 return DebuggerManagerImpl.createDebugParameters(javaParameters, debuggerSettings, false);
146 public SettingsEditor<GenericDebuggerRunnerSettings> getSettingsEditor(final Executor executor, RunConfiguration configuration) {
147 if (configuration instanceof RunConfigurationWithRunnerSettings) {
148 if (((RunConfigurationWithRunnerSettings)configuration).isSettingsNeeded()) {
149 return new GenericDebuggerParametersRunnerConfigurable(configuration.getProject());