/* * Copyright (C) 2013 The Android Open Source Project * * 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 com.android.tools.idea.gradle.project; import com.android.sdklib.repository.FullRevision; import com.google.common.annotations.VisibleForTesting; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.externalSystem.model.settings.LocationSettingType; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextComponentAccessor; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.JBLabel; import org.jdesktop.swingx.JXLabel; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.service.GradleInstallationManager; import org.jetbrains.plugins.gradle.util.GradleBundle; import org.jetbrains.plugins.gradle.util.GradleConstants; import org.jetbrains.plugins.gradle.util.GradleUtil; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.io.File; import static com.android.tools.idea.gradle.util.GradleUtil.getGradleVersion; /** * Dialog where users select the path of the local Gradle installation to use when importing a project. */ public class ChooseGradleHomeDialog extends DialogWrapper { @VisibleForTesting public static final String VALIDATION_MESSAGE_CLIENT_PROPERTY = "validation.message"; @NotNull private final GradleInstallationManager myInstallationManager; @Nullable private final String myMinimumGradleVersion; private TextFieldWithBrowseButton myGradleHomePathField; private JBLabel myGradleHomeLabel; private JPanel myPanel; private JXLabel myDescriptionLabel; public ChooseGradleHomeDialog() { this(null); } public ChooseGradleHomeDialog(@Nullable String minimumGradleVersion) { super(null); myMinimumGradleVersion = minimumGradleVersion; myInstallationManager = ServiceManager.getService(GradleInstallationManager.class); init(); initValidation(); setTitle("Import Gradle Project"); FileChooserDescriptor fileChooserDescriptor = GradleUtil.getGradleHomeFileChooserDescriptor(); myGradleHomePathField.addBrowseFolderListener("", GradleBundle.message("gradle.settings.text.home.path"), null, fileChooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT, false); myGradleHomeLabel.setLabelFor(myGradleHomePathField.getTextField()); // This prevents the weird sizing in Linux. getPeer().getWindow().pack(); myGradleHomePathField.setText(GradleUtil.getLastUsedGradleHome()); myGradleHomePathField.getTextField().getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { initValidation(); } @Override public void removeUpdate(DocumentEvent e) { initValidation(); } @Override public void changedUpdate(DocumentEvent e) { } }); } public void setDescription(@NotNull String descriptionLabel) { myDescriptionLabel.setText(descriptionLabel); } @Nullable @Override protected JComponent createCenterPanel() { return myPanel; } @Nullable @Override protected ValidationInfo doValidate() { LocationSettingType locationSettingType = validateLocation(); switch (locationSettingType) { case EXPLICIT_CORRECT: ValidationInfo validationInfo = validateMinimumGradleVersion(); if (validationInfo != null) { return validationInfo; } return super.doValidate(); default: return newPathIsInvalidInfo(locationSettingType.getDescription(GradleConstants.SYSTEM_ID)); } } @NotNull private LocationSettingType validateLocation() { String gradleHome = getEnteredGradleHomePath(); if (gradleHome.isEmpty()) { return LocationSettingType.UNKNOWN; } File gradleHomePath = getGradleHomePath(gradleHome); return myInstallationManager.isGradleSdkHome(gradleHomePath) ? LocationSettingType.EXPLICIT_CORRECT : LocationSettingType.EXPLICIT_INCORRECT; } @Nullable private ValidationInfo validateMinimumGradleVersion() { if (!StringUtil.isEmpty(myMinimumGradleVersion)) { // When we reach this point we know the path entered is a valid Gradle home path. Now we need to verify the version of Gradle at that // location is equal or greater than the one in myMinimumGradleVersion. FullRevision minimum = FullRevision.parseRevision(myMinimumGradleVersion); File gradleHomePath = getGradleHomePath(getEnteredGradleHomePath()); FullRevision current = getGradleVersion(gradleHomePath); if (current == null) { return newPathIsInvalidInfo("Unable to detect Gradle version"); } if (minimum.compareTo(current) > 0) { return newPathIsInvalidInfo(String.format("Gradle %1$s or newer is required", myMinimumGradleVersion)); } } return null; } @NotNull private ValidationInfo newPathIsInvalidInfo(@NotNull String msg) { storeErrorMessage(msg); JTextField textField = myGradleHomePathField.getTextField(); return new ValidationInfo(msg, textField); } private void storeErrorMessage(@NotNull String msg) { myGradleHomePathField.putClientProperty(VALIDATION_MESSAGE_CLIENT_PROPERTY, msg); } @NotNull private static File getGradleHomePath(@NotNull String gradleHome) { return new File(FileUtil.toSystemDependentName(gradleHome)); } public void storeLastUsedGradleHome() { GradleUtil.storeLastUsedGradleHome(getEnteredGradleHomePath()); } @NotNull public String getEnteredGradleHomePath() { return myGradleHomePathField.getText(); } }