IDEA-149592 Select Gradle JVM java automatically

This commit is contained in:
Vladislav.Soroka
2017-12-01 18:11:17 +03:00
parent b30f70fdd0
commit 9047d2f00c
11 changed files with 188 additions and 44 deletions
@@ -53,7 +53,7 @@ public class ExternalSystemJdkUtil {
}
}
if (project == null) {
if (project == null || project.isDefault()) {
Sdk recent = ProjectJdkTable.getInstance().findMostRecentSdkOfType(JavaSdk.getInstance());
return recent != null ? recent : JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
}
@@ -93,6 +93,12 @@ public class ExternalSystemJdkUtil {
}
}
Sdk mostRecentSdk = ProjectJdkTable.getInstance().findMostRecentSdk(
sdk -> sdk.getSdkType() == JavaSdk.getInstance() && isValidJdk(sdk.getHomePath()));
if (mostRecentSdk != null) {
return Pair.create(mostRecentSdk.getName(), mostRecentSdk);
}
if (!ApplicationManager.getApplication().isUnitTestMode()) {
String javaHome = System.getenv("JAVA_HOME");
if (isValidJdk(javaHome)) {
@@ -100,12 +106,6 @@ public class ExternalSystemJdkUtil {
}
}
for (Sdk projectJdk : ProjectJdkTable.getInstance().getAllJdks()) {
if (isValidJdk(projectJdk.getHomePath())) {
return Pair.create(projectJdk.getName(), projectJdk);
}
}
return Pair.create(USE_INTERNAL_JAVA, JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk());
}
@@ -12,6 +12,7 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.internal.InternalExternalProjectInfo;
import com.intellij.openapi.externalSystem.model.project.ProjectData;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil;
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
import com.intellij.openapi.externalSystem.service.project.*;
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
@@ -27,11 +28,13 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesConfigurator;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -107,13 +110,26 @@ public abstract class AbstractExternalProjectImportBuilder<C extends AbstractImp
}
public void prepare(@NotNull WizardContext context) {
if (context.getProjectJdk() == null) {
context.setProjectJdk(resolveProjectJdk(context));
}
myControl.setShowProjectFormatPanel(context.isCreatingNewProject());
myControl.reset();
myControl.reset(context);
String pathToUse = getFileToImport();
myControl.setLinkedProjectPath(pathToUse);
doPrepare(context);
}
@Nullable
protected Sdk resolveProjectJdk(@NotNull WizardContext context) {
Project project = context.getProject() != null ? context.getProject() : ProjectManager.getInstance().getDefaultProject();
final Pair<String, Sdk> sdkPair = ExternalSystemJdkUtil.getAvailableJdk(project);
if (!ExternalSystemJdkUtil.USE_INTERNAL_JAVA.equals(sdkPair.first)) {
return sdkPair.second;
}
return null;
}
protected abstract void doPrepare(@NotNull WizardContext context);
@Override
@@ -89,6 +89,7 @@ public class ExternalModuleSettingsStep<S extends ExternalProjectSettings> exten
if (contentPath != null) {
myControl.getInitialSettings().setExternalProjectPath(contentPath);
}
myControl.reset(true, myContext);
}
@Override
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.externalSystem.service.settings;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.externalSystem.util.ExternalSystemSettingsControl;
@@ -117,7 +118,16 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
reset(false);
}
@Override
public void reset(@Nullable WizardContext wizardContext) {
reset(false, wizardContext);
}
public void reset(boolean isDefaultModuleCreation) {
reset(isDefaultModuleCreation, null);
}
public void reset(boolean isDefaultModuleCreation, @Nullable WizardContext wizardContext) {
if (!myCustomizer.isUseAutoImportBoxHidden() && myUseAutoImportBox != null) {
myUseAutoImportBox.setSelected(getInitialSettings().isUseAutoImport());
}
@@ -133,11 +143,15 @@ public abstract class AbstractExternalProjectSettingsControl<S extends ExternalP
boolean useQualifiedModuleNames = getInitialSettings().isUseQualifiedModuleNames();
myUseModuleGroupsRadioButton.setSelected(!useQualifiedModuleNames);
myUseQualifiedModuleNamesRadioButton.setSelected(useQualifiedModuleNames);
resetExtraSettings(isDefaultModuleCreation);
resetExtraSettings(isDefaultModuleCreation, wizardContext);
}
protected abstract void resetExtraSettings(boolean isDefaultModuleCreation);
protected void resetExtraSettings(boolean isDefaultModuleCreation, @Nullable WizardContext wizardContext) {
resetExtraSettings(isDefaultModuleCreation);
}
@Override
public void apply(@NotNull S settings) {
settings.setModules(myInitialSettings.getModules());
@@ -218,12 +218,16 @@ public abstract class AbstractImportFromExternalSystemControl<
}
public void reset() {
reset(null);
}
public void reset(@Nullable WizardContext wizardContext) {
myLinkedProjectPathField.setNameComponentVisible(false);
myLinkedProjectPathField.setNameValue("untitled");
myLinkedProjectPathField.setPath("");
myProjectSettingsControl.reset();
myProjectSettingsControl.reset(wizardContext);
if (mySystemSettingsControl != null) {
mySystemSettingsControl.reset();
mySystemSettingsControl.reset(wizardContext);
}
if (hideableSystemSettingsPanel != null) {
hideableSystemSettingsPanel.setOn(false);
@@ -16,6 +16,7 @@
package com.intellij.openapi.externalSystem.service.ui;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkException;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil;
@@ -104,6 +105,14 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
@NotNull ProjectSdksModel jdksModel,
@Nullable String actionGroupTitle,
@Nullable Condition<SdkTypeId> creationFilter) {
setSetupButton(setUpButton, jdksModel, actionGroupTitle, creationFilter, null);
}
public void setSetupButton(@NotNull JButton setUpButton,
@NotNull ProjectSdksModel jdksModel,
@Nullable String actionGroupTitle,
@Nullable Condition<SdkTypeId> creationFilter,
@Nullable WizardContext wizardContext) {
Arrays.stream(setUpButton.getActionListeners()).forEach(setUpButton::removeActionListener);
setUpButton.addActionListener(e -> {
@@ -121,7 +130,7 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
else {
jdkName = existingJdk.getName();
}
refreshData(jdkName);
refreshData(jdkName, wizardContext != null ? wizardContext.getProjectJdk() : null);
}, creationFilter);
final DataContext dataContext = DataManager.getInstance().getDataContext(this);
if (group.getChildrenCount() > 1) {
@@ -156,7 +165,11 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
}
public void refreshData(@Nullable String selectedValue) {
Map<String, JdkComboBoxItem> jdkMap = collectComboBoxItem();
refreshData(selectedValue, null);
}
public void refreshData(@Nullable String selectedValue, @Nullable Sdk projectJdk) {
Map<String, JdkComboBoxItem> jdkMap = collectComboBoxItem(projectJdk);
if (selectedValue != null && !jdkMap.containsKey(selectedValue)) {
assert selectedValue.length() > 0;
jdkMap.put(selectedValue, new JdkComboBoxItem(selectedValue, selectedValue, "", false));
@@ -164,19 +177,19 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
removeAllItems();
ComboBoxModel<JdkComboBoxItem> comboBoxModel = getModel();
for (Map.Entry<String, JdkComboBoxItem> entry : jdkMap.entrySet()) {
//noinspection unchecked
((DefaultComboBoxModel)getModel()).addElement(entry.getValue());
((MutableComboBoxModel<JdkComboBoxItem>)comboBoxModel).addElement(entry.getValue());
}
select((DefaultComboBoxModel)getModel(), selectedValue);
select(comboBoxModel, selectedValue);
}
private static void select(DefaultComboBoxModel model, Object value) {
private static void select(ComboBoxModel<JdkComboBoxItem> model, Object value) {
for (int i = 0; i < model.getSize(); i++) {
JdkComboBoxItem comboBoxUtil = (JdkComboBoxItem)model.getElementAt(i);
if (comboBoxUtil.jdkName.equals(value)) {
model.setSelectedItem(comboBoxUtil);
JdkComboBoxItem item = model.getElementAt(i);
if (item.jdkName.equals(value)) {
model.setSelectedItem(item);
return;
}
}
@@ -192,13 +205,13 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
return item != null ? ((JdkComboBoxItem)item).jdkName : null;
}
private Map<String, JdkComboBoxItem> collectComboBoxItem() {
private Map<String, JdkComboBoxItem> collectComboBoxItem(@Nullable Sdk projectSdk) {
Map<String, JdkComboBoxItem> result = new LinkedHashMap<>();
for (Sdk projectJdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
String name = projectJdk.getName();
String comment = buildComment(projectJdk);
result.put(name, new JdkComboBoxItem(name, name, comment, ((SdkType)projectJdk.getSdkType()).sdkHasValidPath(projectJdk)));
for (Sdk sdk : ProjectJdkTable.getInstance().getSdksOfType(JavaSdk.getInstance())) {
String name = sdk.getName();
String comment = buildComment(sdk);
result.put(name, new JdkComboBoxItem(name, name, comment, ((SdkType)sdk.getSdkType()).sdkHasValidPath(sdk)));
}
if(suggestJre) {
@@ -213,13 +226,15 @@ public class ExternalSystemJdkComboBox extends ComboBoxWithWidePopup<ExternalSys
));
}
if (myProject != null && !myProject.isDisposed()) {
final Sdk projectSdk = ProjectRootManager.getInstance(myProject).getProjectSdk();
if (projectSdk == null) {
if (myProject != null && !myProject.isDisposed()) {
projectSdk = ProjectRootManager.getInstance(myProject).getProjectSdk();
}
}
if (projectSdk != null) {
result.put(ExternalSystemJdkUtil.USE_PROJECT_JDK,
new JdkComboBoxItem(
ExternalSystemJdkUtil.USE_PROJECT_JDK, "Use Project JDK",
projectSdk == null ? "not defined yet" : buildComment(projectSdk), projectSdk != null
));
new JdkComboBoxItem(ExternalSystemJdkUtil.USE_PROJECT_JDK, "Use Project JDK", buildComment(projectSdk), true));
}
String javaHomePath = System.getenv("JAVA_HOME");
@@ -15,8 +15,10 @@
*/
package com.intellij.openapi.externalSystem.util;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.options.ConfigurationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -46,6 +48,13 @@ public interface ExternalSystemSettingsControl<S> {
*/
void reset();
/**
* Asks current control to reset its state to the initial one.
*/
default void reset(@Nullable WizardContext wizardContext) {
reset();
}
/**
* @return {@code true} if settings exposed by the current control have been modified; {@code false} otherwise
*/
@@ -17,13 +17,19 @@ import com.intellij.openapi.externalSystem.service.ui.ExternalProjectDataSelecto
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.util.ObjectUtils;
import gnu.trove.THashSet;
import icons.GradleIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,14 +41,20 @@ import org.jetbrains.plugins.gradle.util.GradleConstants;
import javax.swing.*;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* @author Denis Zhdanov
* @since 4/15/13 2:29 PM
*/
public class GradleProjectImportBuilder extends AbstractExternalProjectImportBuilder<ImportFromGradleControl> {
private static final Pattern JAVA_VERSION = Pattern.compile("java version \"(\\d.*)\"");
/**
* @deprecated use {@link GradleProjectImportBuilder#GradleProjectImportBuilder(ProjectDataManager)}
*/
@@ -65,6 +77,45 @@ public class GradleProjectImportBuilder extends AbstractExternalProjectImportBui
return GradleIcons.Gradle;
}
@Nullable
@Override
protected Sdk resolveProjectJdk(@NotNull WizardContext context) {
// gradle older than 4.2.1 doesn't support new java the version number format like 9.0.1, see https://github.com/gradle/gradle/issues/2992
Condition<Sdk> sdkCondition = sdk -> {
String version = getVersion(sdk);
return StringUtil.compareVersionNumbers(version, "1.6") > 0 &&
StringUtil.compareVersionNumbers(version, "9") < 0;
};
Sdk mostRecentSdk = ProjectJdkTable.getInstance().findMostRecentSdk(
sdk -> sdk.getSdkType() == JavaSdk.getInstance() && sdkCondition.value(sdk));
if (mostRecentSdk != null) {
return mostRecentSdk;
}
Set<String> existingPaths =
new THashSet<>(Arrays.stream(ProjectJdkTable.getInstance().getAllJdks()).map(sdk -> sdk.getHomePath()).collect(Collectors.toSet()),
FileUtil.PATH_HASHING_STRATEGY);
for (String javaHome : JavaSdk.getInstance().suggestHomePaths()) {
if (!existingPaths.contains(FileUtil.toCanonicalPath(javaHome))) {
JavaSdk javaSdk = JavaSdk.getInstance();
Sdk jdk = javaSdk.createJdk(ObjectUtils.notNull(javaSdk.suggestSdkName(null, javaHome), ""), javaHome);
if (sdkCondition.value(jdk)) {
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().addJdk(jdk));
return jdk;
}
}
}
Project project = context.getProject() != null ? context.getProject() : ProjectManager.getInstance().getDefaultProject();
final Pair<String, Sdk> sdkPair = ExternalSystemJdkUtil.getAvailableJdk(project);
if (!ExternalSystemJdkUtil.USE_INTERNAL_JAVA.equals(sdkPair.first)) {
return sdkPair.second;
}
return null;
}
@Override
protected void doPrepare(@NotNull WizardContext context) {
String pathToUse = getFileToImport();
@@ -75,10 +126,6 @@ public class GradleProjectImportBuilder extends AbstractExternalProjectImportBui
final ImportFromGradleControl importFromGradleControl = getControl(context.getProject());
importFromGradleControl.setLinkedProjectPath(pathToUse);
final Pair<String, Sdk> sdkPair = ExternalSystemJdkUtil.getAvailableJdk(context.getProject());
if (sdkPair != null && !ExternalSystemJdkUtil.USE_INTERNAL_JAVA.equals(sdkPair.first)) {
importFromGradleControl.getProjectSettings().setGradleJvm(sdkPair.first);
}
}
@Override
@@ -191,4 +238,15 @@ public class GradleProjectImportBuilder extends AbstractExternalProjectImportBui
}
return project;
}
@Nullable
private static String getVersion(Sdk sdk) {
String versionString = sdk.getVersionString();
if (versionString == null) return null;
Matcher matcher = JAVA_VERSION.matcher(versionString.trim());
if (matcher.matches()) {
return matcher.group(1);
}
return versionString;
}
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.service.settings;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.externalSystem.service.settings.AbstractExternalProjectSettingsControl;
import com.intellij.openapi.externalSystem.service.settings.AbstractImportFromExternalSystemControl;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
@@ -68,7 +69,12 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting
@Override
protected void resetExtraSettings(boolean isDefaultModuleCreation) {
myBuilder.reset(getProject(), getInitialSettings(), isDefaultModuleCreation);
resetExtraSettings(isDefaultModuleCreation, null);
}
@Override
protected void resetExtraSettings(boolean isDefaultModuleCreation, @Nullable WizardContext wizardContext) {
myBuilder.reset(getProject(), getInitialSettings(), isDefaultModuleCreation, wizardContext);
}
public void update(@Nullable String linkedProjectPath, boolean isDefaultModuleCreation) {
@@ -86,7 +92,6 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting
*/
public void setCurrentProject(@Nullable Project project) {
super.setCurrentProject(project);
myBuilder.reset(getProject(), getInitialSettings(), false);
}
@Override
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.service.settings;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.externalSystem.service.settings.ExternalSystemSettingsControlCustomizer;
import com.intellij.openapi.externalSystem.util.PaintAwarePanel;
import com.intellij.openapi.options.ConfigurationException;
@@ -65,7 +66,14 @@ public interface GradleProjectSettingsControlBuilder {
*/
boolean isModified();
void reset(Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation);
void reset(@Nullable Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation);
default void reset(@Nullable Project project,
GradleProjectSettings settings,
boolean isDefaultModuleCreation,
@Nullable WizardContext wizardContext) {
reset(project, settings, isDefaultModuleCreation);
}
void createAndFillControls(PaintAwarePanel content, int indentLevel);
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.service.settings;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.components.ServiceManager;
@@ -28,6 +29,7 @@ import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.FixedSizeButton;
@@ -458,7 +460,15 @@ public class IdeaGradleProjectSettingsControlBuilder implements GradleProjectSet
}
@Override
public void reset(Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation) {
public void reset(@Nullable Project project, GradleProjectSettings settings, boolean isDefaultModuleCreation) {
reset(project, settings, isDefaultModuleCreation, null);
}
@Override
public void reset(@Nullable Project project,
GradleProjectSettings settings,
boolean isDefaultModuleCreation,
@Nullable WizardContext wizardContext) {
String gradleHome = settings.getGradleHome();
if (myGradleHomePathField != null) {
myGradleHomePathField.setText(gradleHome == null ? "" : gradleHome);
@@ -471,7 +481,7 @@ public class IdeaGradleProjectSettingsControlBuilder implements GradleProjectSet
myStoreExternallyCheckBox.setSelected(settings.isStoreProjectFilesExternally());
}
resetGradleJdkComboBox(project, settings);
resetGradleJdkComboBox(project, settings, wizardContext);
resetWrapperControls(settings.getExternalProjectPath(), settings, isDefaultModuleCreation);
if (myUseLocalDistributionButton != null && !myUseLocalDistributionButton.isSelected()) {
@@ -535,15 +545,19 @@ public class IdeaGradleProjectSettingsControlBuilder implements GradleProjectSet
return this;
}
private void resetGradleJdkComboBox(@Nullable final Project project, GradleProjectSettings settings) {
private void resetGradleJdkComboBox(@Nullable final Project project,
GradleProjectSettings settings,
@Nullable WizardContext wizardContext) {
if (myGradleJdkComboBox == null) return;
final String gradleJvm = settings.getGradleJvm();
myGradleJdkComboBox.setProject(project);
final String sdkItem = ObjectUtils.nullizeByCondition(gradleJvm, s -> (project == null && StringUtil.equals(USE_PROJECT_JDK, s)) || StringUtil.isEmpty(s));
Sdk projectJdk = wizardContext != null ? wizardContext.getProjectJdk() : null;
final String sdkItem = ObjectUtils.nullizeByCondition(gradleJvm, s ->
(projectJdk == null && project == null && StringUtil.equals(USE_PROJECT_JDK, s)) || StringUtil.isEmpty(s));
myGradleJdkComboBox.refreshData(sdkItem);
myGradleJdkComboBox.refreshData(sdkItem, projectJdk);
if (myGradleJdkSetUpButton != null) {
ProjectSdksModel sdksModel = ProjectStructureConfigurable.getInstance(
project == null || project.isDisposed() ? ProjectManager.getInstance().getDefaultProject() : project).getProjectJdksModel();