| /* |
| * Copyright (C) 2014 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.structure.gradle; |
| |
| import com.android.SdkConstants; |
| import com.android.tools.idea.gradle.parser.BuildFileKey; |
| import com.android.tools.idea.gradle.parser.GradleBuildFile; |
| import com.android.tools.idea.gradle.util.GradleUtil; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Maps; |
| import com.google.common.collect.Sets; |
| import com.intellij.icons.AllIcons; |
| import com.intellij.openapi.command.CommandProcessor; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.options.ConfigurationException; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.ui.NamedConfigurable; |
| import com.intellij.openapi.vfs.ReadonlyStatusHandler; |
| import com.intellij.openapi.vfs.VfsUtil; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.ActionRunner; |
| import org.jetbrains.annotations.Nls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import javax.swing.*; |
| import java.io.File; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * A standard {@linkplan Configurable} instance that allows editing of project-wide project structure parameters, including the top-level |
| * build file. |
| */ |
| public class AndroidProjectConfigurable extends NamedConfigurable implements KeyValuePane.ModificationListener { |
| private static final Logger LOG = Logger.getInstance(AndroidProjectConfigurable.class); |
| private static final String DISPLAY_NAME = "Project"; |
| private final KeyValuePane myKeyValuePane; |
| private final Project myProject; |
| private final GradleBuildFile myGradleBuildFile; |
| private final Map<BuildFileKey, Object> myProjectProperties = Maps.newHashMap(); |
| private Set<BuildFileKey> myModifiedKeys = Sets.newHashSet(); |
| |
| public static final ImmutableList<BuildFileKey> PROJECT_PROPERTIES = |
| ImmutableList.of(BuildFileKey.GRADLE_WRAPPER_VERSION, BuildFileKey.PLUGIN_VERSION, BuildFileKey.PLUGIN_REPOSITORY, |
| BuildFileKey.ALLPROJECTS_LIBRARY_REPOSITORY); |
| |
| public AndroidProjectConfigurable(Project project) { |
| if (project.isDefault()) { |
| throw new IllegalArgumentException("Can't instantiate an AndroidProjectConfigurable with the default project."); |
| } |
| myKeyValuePane = new KeyValuePane(project, this); |
| myProject = project; |
| VirtualFile vf = project.getBaseDir().findChild(SdkConstants.FN_BUILD_GRADLE); |
| if (vf != null) { |
| myGradleBuildFile = new GradleBuildFile(vf, project); |
| } else { |
| myGradleBuildFile = null; |
| } |
| } |
| |
| @Override |
| public void setDisplayName(String name) { |
| } |
| |
| @Override |
| public Object getEditableObject() { |
| return myProject; |
| } |
| |
| @Override |
| public String getBannerSlogan() { |
| return DISPLAY_NAME; |
| } |
| |
| @Override |
| public JComponent createOptionsPanel() { |
| myKeyValuePane.init(myGradleBuildFile, PROJECT_PROPERTIES); |
| return myKeyValuePane; |
| } |
| |
| @Nls |
| @Override |
| public String getDisplayName() { |
| return DISPLAY_NAME; |
| } |
| |
| @Nullable |
| @Override |
| public String getHelpTopic() { |
| return null; |
| } |
| |
| @Override |
| public boolean isModified() { |
| return !myModifiedKeys.isEmpty(); |
| } |
| |
| @Override |
| public void modified(@NotNull BuildFileKey key) { |
| myModifiedKeys.add(key); |
| } |
| |
| @Override |
| public void apply() throws ConfigurationException { |
| if (myGradleBuildFile == null) { |
| return; |
| } |
| VirtualFile file = myGradleBuildFile.getFile(); |
| if (!ReadonlyStatusHandler.ensureFilesWritable(myProject, file)) { |
| throw new ConfigurationException(String.format("Build file %1$s is not writable", file.getPath())); |
| } |
| |
| CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| ActionRunner.runInsideWriteAction(new ActionRunner.InterruptibleRunnable() { |
| @Override |
| public void run() throws Exception { |
| for (BuildFileKey key : PROJECT_PROPERTIES) { |
| if (key == BuildFileKey.GRADLE_WRAPPER_VERSION || !myModifiedKeys.contains(key)) { |
| continue; |
| } |
| Object value = myProjectProperties.get(key); |
| if (value != null) { |
| myGradleBuildFile.setValue(key, value); |
| } else { |
| myGradleBuildFile.removeValue(null, key); |
| } |
| } |
| Object wrapperVersion = myProjectProperties.get(BuildFileKey.GRADLE_WRAPPER_VERSION); |
| File wrapperPropertiesFile = GradleUtil.findWrapperPropertiesFile(myProject); |
| if (wrapperVersion != null && wrapperPropertiesFile != null) { |
| boolean updated = GradleUtil.updateGradleDistributionUrl(wrapperVersion.toString(), wrapperPropertiesFile); |
| if (updated) { |
| VirtualFile virtualFile = VfsUtil.findFileByIoFile(wrapperPropertiesFile, true); |
| if (virtualFile != null) { |
| virtualFile.refresh(false, false); |
| } |
| } |
| } |
| myModifiedKeys.clear(); |
| } |
| }); |
| } |
| catch (Exception e) { |
| LOG.error("Error while applying changes", e); |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public void reset() { |
| myProjectProperties.clear(); |
| if (myGradleBuildFile == null) { |
| return; |
| } |
| |
| for (BuildFileKey key : PROJECT_PROPERTIES) { |
| Object value = myGradleBuildFile.getValue(key); |
| if (value != null) { |
| myProjectProperties.put(key, value); |
| } |
| } |
| try { |
| File wrapperPropertiesFile = GradleUtil.findWrapperPropertiesFile(myProject); |
| if (wrapperPropertiesFile != null) { |
| String wrapperVersion = GradleUtil.getGradleWrapperVersion(wrapperPropertiesFile); |
| myProjectProperties.put(BuildFileKey.GRADLE_WRAPPER_VERSION, wrapperVersion); |
| } |
| } catch (Exception e) { |
| LOG.warn("Error while saving Gradle wrapper properties", e); |
| } |
| myKeyValuePane.setCurrentBuildFileObject(myProjectProperties); |
| myKeyValuePane.updateUiFromCurrentObject(); |
| } |
| |
| @Override |
| public void disposeUIResources() { |
| } |
| |
| @Nullable |
| @Override |
| public Icon getIcon(boolean expanded) { |
| return AllIcons.Nodes.Project; |
| } |
| } |