blob: 2c7361f8f5717e89e0e37bf97b7bc7632abb6ca0 [file] [log] [blame]
/*
* Copyright 2000-2014 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 org.jetbrains.idea.devkit.run;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkType;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PlatformUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.DevKitBundle;
import org.jetbrains.idea.devkit.projectRoots.IdeaJdk;
import org.jetbrains.idea.devkit.projectRoots.Sandbox;
import java.io.File;
import java.io.IOException;
public class PluginRunConfiguration extends RunConfigurationBase implements ModuleRunConfiguration {
private Module myModule;
private String myModuleName;
public String VM_PARAMETERS;
public String PROGRAM_PARAMETERS;
@NonNls private static final String NAME = "name";
@NonNls private static final String MODULE = "module";
@NonNls private static final String ALTERNATIVE_PATH_ELEMENT = "alternative-path";
@NonNls private static final String PATH = "path";
@NonNls private static final String ALTERNATIVE_PATH_ENABLED_ATTR = "alternative-path-enabled";
private String ALTERNATIVE_JRE_PATH = null;
private boolean ALTERNATIVE_JRE_PATH_ENABLED = false;
public PluginRunConfiguration(final Project project, final ConfigurationFactory factory, final String name) {
super(project, factory, name);
}
@NotNull
@Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new PluginRunConfigurationEditor(this);
}
@Override
public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
if (getModule() == null){
throw new ExecutionException(DevKitBundle.message("run.configuration.no.module.specified"));
}
final ModuleRootManager rootManager = ModuleRootManager.getInstance(getModule());
final Sdk jdk = rootManager.getSdk();
if (jdk == null) {
throw CantRunException.noJdkForModule(getModule());
}
final Sdk ideaJdk = IdeaJdk.findIdeaJdk(jdk);
if (ideaJdk == null) {
throw new ExecutionException(DevKitBundle.message("sdk.type.incorrect.common"));
}
String sandboxHome = ((Sandbox)ideaJdk.getSdkAdditionalData()).getSandboxHome();
if (sandboxHome == null){
throw new ExecutionException(DevKitBundle.message("sandbox.no.configured"));
}
try {
sandboxHome = new File(sandboxHome).getCanonicalPath();
}
catch (IOException e) {
throw new ExecutionException(DevKitBundle.message("sandbox.no.configured"));
}
final String canonicalSandbox = sandboxHome;
//copy license from running instance of idea
IdeaLicenseHelper.copyIDEALicense(sandboxHome, ideaJdk);
final JavaCommandLineState state = new JavaCommandLineState(env) {
@Override
protected JavaParameters createJavaParameters() throws ExecutionException {
final JavaParameters params = new JavaParameters();
ParametersList vm = params.getVMParametersList();
fillParameterList(vm, VM_PARAMETERS);
fillParameterList(params.getProgramParametersList(), PROGRAM_PARAMETERS);
Sdk usedIdeaJdk = ideaJdk;
if (isAlternativeJreEnabled() && !StringUtil.isEmptyOrSpaces(getAlternativeJrePath())) {
try {
usedIdeaJdk = (Sdk)usedIdeaJdk.clone();
}
catch (CloneNotSupportedException e) {
throw new ExecutionException(e.getMessage());
}
final SdkModificator sdkToSetUp = usedIdeaJdk.getSdkModificator();
sdkToSetUp.setHomePath(getAlternativeJrePath());
sdkToSetUp.commitChanges();
}
@NonNls String libPath = usedIdeaJdk.getHomePath() + File.separator + "lib";
vm.add("-Xbootclasspath/a:" + libPath + File.separator + "boot.jar");
vm.defineProperty("idea.config.path", canonicalSandbox + File.separator + "config");
vm.defineProperty("idea.system.path", canonicalSandbox + File.separator + "system");
vm.defineProperty("idea.plugins.path", canonicalSandbox + File.separator + "plugins");
if (SystemInfo.isMac) {
vm.defineProperty("idea.smooth.progress", "false");
vm.defineProperty("apple.laf.useScreenMenuBar", "true");
}
if (SystemInfo.isXWindow) {
if (VM_PARAMETERS == null || !VM_PARAMETERS.contains("-Dsun.awt.disablegrab")) {
vm.defineProperty("sun.awt.disablegrab", "true"); // See http://devnet.jetbrains.net/docs/DOC-1142
}
}
if (!vm.hasProperty(PlatformUtils.PLATFORM_PREFIX_KEY)) {
String buildNumber = IdeaJdk.getBuildNumber(usedIdeaJdk.getHomePath());
if (buildNumber != null) {
String prefix = null;
if (buildNumber.startsWith("IC")) {
prefix = PlatformUtils.IDEA_CE_PREFIX;
}
else if (buildNumber.startsWith("PY")) {
prefix = PlatformUtils.PYCHARM_PREFIX;
}
else if (buildNumber.startsWith("PC")) {
prefix = PlatformUtils.PYCHARM_CE_PREFIX;
}
else if (buildNumber.startsWith("RM")) {
prefix = PlatformUtils.RUBY_PREFIX;
}
else if (buildNumber.startsWith("PS")) {
prefix = PlatformUtils.PHP_PREFIX;
}
else if (buildNumber.startsWith("WS")) {
prefix = PlatformUtils.WEB_PREFIX;
}
else if (buildNumber.startsWith("OC")) {
prefix = PlatformUtils.APPCODE_PREFIX;
}
else if (buildNumber.startsWith("CL")) {
prefix = PlatformUtils.CLION_PREFIX;
}
else if (buildNumber.startsWith("DB")) {
prefix = PlatformUtils.DBE_PREFIX;
}
if (prefix != null) {
vm.defineProperty(PlatformUtils.PLATFORM_PREFIX_KEY, prefix);
}
}
}
params.setWorkingDirectory(usedIdeaJdk.getHomePath() + File.separator + "bin" + File.separator);
params.setJdk(usedIdeaJdk);
params.getClassPath().addFirst(libPath + File.separator + "log4j.jar");
params.getClassPath().addFirst(libPath + File.separator + "jdom.jar");
params.getClassPath().addFirst(libPath + File.separator + "trove4j.jar");
params.getClassPath().addFirst(libPath + File.separator + "openapi.jar");
params.getClassPath().addFirst(libPath + File.separator + "util.jar");
params.getClassPath().addFirst(libPath + File.separator + "extensions.jar");
params.getClassPath().addFirst(libPath + File.separator + "bootstrap.jar");
params.getClassPath().addFirst(libPath + File.separator + "idea.jar");
params.getClassPath().addFirst(libPath + File.separator + "idea_rt.jar");
params.getClassPath().addFirst(((JavaSdkType)usedIdeaJdk.getSdkType()).getToolsPath(usedIdeaJdk));
params.setMainClass("com.intellij.idea.Main");
return params;
}
};
return state;
}
public String getAlternativeJrePath() {
return ALTERNATIVE_JRE_PATH;
}
public void setAlternativeJrePath(String ALTERNATIVE_JRE_PATH) {
this.ALTERNATIVE_JRE_PATH = ALTERNATIVE_JRE_PATH;
}
public boolean isAlternativeJreEnabled() {
return ALTERNATIVE_JRE_PATH_ENABLED;
}
public void setAlternativeJreEnabled(boolean ALTERNATIVE_JRE_PATH_ENABLED) {
this.ALTERNATIVE_JRE_PATH_ENABLED = ALTERNATIVE_JRE_PATH_ENABLED;
}
private static void fillParameterList(ParametersList list, @Nullable String value) {
if (value == null) return;
for (String parameter : value.split(" ")) {
if (parameter != null && parameter.length() > 0) {
list.add(parameter);
}
}
}
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
if (getModule() == null) {
throw new RuntimeConfigurationException(DevKitBundle.message("run.configuration.no.module.specified"));
}
String moduleName = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
return getModule().getName();
}
});
if (ModuleManager.getInstance(getProject()).findModuleByName(moduleName) == null){
throw new RuntimeConfigurationException(DevKitBundle.message("run.configuration.no.module.specified"));
}
final ModuleRootManager rootManager = ModuleRootManager.getInstance(getModule());
final Sdk sdk = rootManager.getSdk();
if (sdk == null) {
throw new RuntimeConfigurationException(DevKitBundle.message("sdk.no.specified", moduleName));
}
if (IdeaJdk.findIdeaJdk(sdk) == null) {
throw new RuntimeConfigurationException(DevKitBundle.message("sdk.type.incorrect", moduleName));
}
}
@Override
@NotNull
public Module[] getModules() {
final Module module = getModule();
return module != null ? new Module[]{module} : Module.EMPTY_ARRAY;
}
@Override
public void readExternal(Element element) throws InvalidDataException {
Element module = element.getChild(MODULE);
if (module != null) {
myModuleName = module.getAttributeValue(NAME);
}
DefaultJDOMExternalizer.readExternal(this, element);
final Element altElement = element.getChild(ALTERNATIVE_PATH_ELEMENT);
if (altElement != null) {
ALTERNATIVE_JRE_PATH = altElement.getAttributeValue(PATH);
final String enabledAttr = altElement.getAttributeValue(ALTERNATIVE_PATH_ENABLED_ATTR);
ALTERNATIVE_JRE_PATH_ENABLED = enabledAttr != null && Boolean.parseBoolean(enabledAttr);
}
super.readExternal(element);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
Element moduleElement = new Element(MODULE);
moduleElement.setAttribute(NAME, ApplicationManager.getApplication().runReadAction(new Computable<String>() {
@Override
public String compute() {
final Module module = getModule();
return module != null ? module.getName()
: myModuleName != null ? myModuleName : "";
}
}));
element.addContent(moduleElement);
DefaultJDOMExternalizer.writeExternal(this, element);
if (!StringUtil.isEmptyOrSpaces(ALTERNATIVE_JRE_PATH)) {
Element altElement = new Element(ALTERNATIVE_PATH_ELEMENT);
altElement.setAttribute(PATH, ALTERNATIVE_JRE_PATH);
altElement.setAttribute(ALTERNATIVE_PATH_ENABLED_ATTR, String.valueOf(ALTERNATIVE_JRE_PATH_ENABLED));
element.addContent(altElement);
}
super.writeExternal(element);
}
@Nullable
public Module getModule() {
if (myModule == null && myModuleName != null){
myModule = ModuleManager.getInstance(getProject()).findModuleByName(myModuleName);
}
if (myModule != null && myModule.isDisposed()) {
myModule = null;
}
return myModule;
}
public void setModule(Module module) {
myModule = module;
}
}