cleanup: remove useless '@author nik' from javadoc comments
[idea/community.git] / java / execution / impl / src / com / intellij / execution / application / BaseJavaApplicationCommandLineState.java
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 com.intellij.execution.application;
3
4 import com.intellij.debugger.impl.RemoteConnectionBuilder;
5 import com.intellij.debugger.settings.DebuggerSettings;
6 import com.intellij.execution.*;
7 import com.intellij.execution.configurations.*;
8 import com.intellij.execution.filters.ArgumentFileFilter;
9 import com.intellij.execution.process.KillableColoredProcessHandler;
10 import com.intellij.execution.process.OSProcessHandler;
11 import com.intellij.execution.process.ProcessTerminatedListener;
12 import com.intellij.execution.runners.ExecutionEnvironment;
13 import com.intellij.execution.target.*;
14 import com.intellij.execution.target.java.JavaLanguageRuntimeConfiguration;
15 import com.intellij.execution.target.local.LocalTargetEnvironmentFactory;
16 import com.intellij.execution.util.JavaParametersUtil;
17 import com.intellij.openapi.application.Experiments;
18 import com.intellij.openapi.progress.EmptyProgressIndicator;
19 import com.intellij.openapi.projectRoots.JavaSdkVersion;
20 import com.intellij.openapi.projectRoots.JdkUtil;
21 import com.intellij.openapi.util.text.StringUtil;
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
24
25 import java.io.File;
26 import java.util.Map;
27 import java.util.Optional;
28
29 public abstract class BaseJavaApplicationCommandLineState<T extends RunConfigurationBase & CommonJavaRunConfigurationParameters>
30   extends JavaCommandLineState implements RemoteConnectionCreator {
31
32   @NotNull protected final T myConfiguration;
33
34   @Nullable private TargetEnvironmentFactory myTargetEnvironmentFactory;
35   @Nullable private RemoteConnection myRemoteConnection;
36
37   public BaseJavaApplicationCommandLineState(ExecutionEnvironment environment, @NotNull final T configuration) {
38     super(environment);
39     myConfiguration = configuration;
40   }
41
42   protected void setupJavaParameters(@NotNull JavaParameters params) throws ExecutionException {
43     JavaParametersUtil.configureConfiguration(params, myConfiguration);
44
45     for (RunConfigurationExtension ext : RunConfigurationExtension.EP_NAME.getExtensionList()) {
46       ext.updateJavaParameters(getConfiguration(), params, getRunnerSettings(), getEnvironment().getExecutor());
47     }
48   }
49
50   @Nullable
51   @Override
52   public RemoteConnection createRemoteConnection(ExecutionEnvironment environment) {
53     //todo[remoteServers]: pull up and support all implementations of JavaCommandLineState
54     try {
55       TargetEnvironmentFactory environmentFactory = getTargetEnvironmentFactory(environment);
56       if (!(environmentFactory instanceof LocalTargetEnvironmentFactory)) {
57         final String remotePort = "12345";
58         final String remoteAddressForVmParams;
59
60         final boolean java9plus = Optional.ofNullable(environmentFactory.getTargetConfiguration())
61           .map(TargetEnvironmentConfiguration::getRuntimes)
62           .map(list -> list.findByType(JavaLanguageRuntimeConfiguration.class))
63           .map(JavaLanguageRuntimeConfiguration::getJavaVersionString)
64           .filter(StringUtil::isNotEmpty)
65           .map(JavaSdkVersion::fromVersionString)
66           .map(v -> v.isAtLeast(JavaSdkVersion.JDK_1_9))
67           .orElse(false);
68
69         if (java9plus) {
70           // IDEA-225182 - hack: pass "host:port" to construct correct VM params, then adjust the connection
71           remoteAddressForVmParams = "*:" + remotePort;
72         }
73         else {
74           remoteAddressForVmParams = remotePort;
75         }
76
77         myRemoteConnection = new RemoteConnectionBuilder(false, DebuggerSettings.SOCKET_TRANSPORT, remoteAddressForVmParams)
78           .suspend(true)
79           .create(getJavaParameters());
80
81         myRemoteConnection.setApplicationAddress(remotePort);
82         if (java9plus) {
83           myRemoteConnection.setApplicationHostName("*");
84         }
85
86         return myRemoteConnection;
87       }
88     }
89     catch (ExecutionException e) {
90       return null;
91     }
92     return null;
93   }
94
95   @Override
96   public boolean isPollConnection() {
97     return true;
98   }
99
100   @NotNull
101   @Override
102   protected OSProcessHandler startProcess() throws ExecutionException {
103     //todo[remoteServers]: pull up and support all implementations of JavaCommandLineState
104     TargetEnvironmentFactory runner = getTargetEnvironmentFactory(getEnvironment());
105     TargetEnvironmentRequest request = runner.createRequest();
106     if (myRemoteConnection != null) {
107       final int remotePort = StringUtil.parseInt(myRemoteConnection.getApplicationAddress(), -1);
108       if (remotePort > 0) {
109         request.bindTargetPort(remotePort).getLocalValue().onSuccess(it -> {
110           myRemoteConnection.setDebuggerHostName("0.0.0.0");
111           myRemoteConnection.setDebuggerAddress(String.valueOf(it));
112         });
113       }
114     }
115
116     TargetedCommandLineBuilder targetedCommandLineBuilder = createTargetedCommandLine(request, runner.getTargetConfiguration());
117     TargetedCommandLine targetedCommandLine = targetedCommandLineBuilder.build();
118     EmptyProgressIndicator indicator = new EmptyProgressIndicator();
119     TargetEnvironment remoteEnvironment = runner.prepareRemoteEnvironment(request, indicator);
120     Process process = remoteEnvironment.createProcess(targetedCommandLine, indicator);
121
122     Map<String, String> content = targetedCommandLineBuilder.getUserData(JdkUtil.COMMAND_LINE_CONTENT);
123     if (content != null) {
124       content.forEach((key, value) -> addConsoleFilters(new ArgumentFileFilter(key, value)));
125     }
126     //todo[remoteServers]: invent the new method for building presentation string
127     String commandRepresentation = StringUtil.join(targetedCommandLine.prepareCommandLine(remoteEnvironment), " ");
128
129     OSProcessHandler handler = new KillableColoredProcessHandler.Silent(process, commandRepresentation,
130                                                                         targetedCommandLine.getCharset(),
131                                                                         targetedCommandLineBuilder.getFilesToDeleteOnTermination());
132     ProcessTerminatedListener.attach(handler);
133     JavaRunConfigurationExtensionManager.getInstance().attachExtensionsToProcess(getConfiguration(), handler, getRunnerSettings());
134     return handler;
135   }
136
137   @NotNull
138   private TargetEnvironmentFactory getTargetEnvironmentFactory(@NotNull ExecutionEnvironment environment)
139     throws ExecutionException {
140     if (myTargetEnvironmentFactory != null) {
141       return myTargetEnvironmentFactory;
142     }
143     if (myConfiguration instanceof TargetEnvironmentAwareRunProfile && Experiments.getInstance().isFeatureEnabled("runtime.environments")) {
144       String targetName = ((TargetEnvironmentAwareRunProfile)myConfiguration).getDefaultTargetName();
145       if (targetName != null) {
146         TargetEnvironmentConfiguration config = TargetEnvironmentsManager.getInstance().getTargets().findByName(targetName);
147         if (config == null) {
148           throw new ExecutionException("Cannot find target " + targetName);
149         }
150         return myTargetEnvironmentFactory = config.createEnvironmentFactory(environment.getProject());
151       }
152     }
153     return myTargetEnvironmentFactory = new LocalTargetEnvironmentFactory();
154   }
155
156   @NotNull
157   @Override
158   protected TargetedCommandLineBuilder createTargetedCommandLine(@NotNull TargetEnvironmentRequest request,
159                                                                  @Nullable TargetEnvironmentConfiguration configuration)
160     throws ExecutionException {
161     TargetedCommandLineBuilder line = super.createTargetedCommandLine(request, configuration);
162     File inputFile = InputRedirectAware.getInputFile(myConfiguration);
163     if (inputFile != null) {
164       line.setInputFile(request.createUpload(inputFile.getAbsolutePath()));
165     }
166     return line;
167   }
168
169   @NotNull
170   protected T getConfiguration() {
171     return myConfiguration;
172   }
173 }