dd749f1813d8f1bbff6b751fa78826b81c6591b5
[idea/community.git] / plugins / gradle / src / org / jetbrains / plugins / gradle / settings / GradleSettings.java
1 // Copyright 2000-2020 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 org.jetbrains.plugins.gradle.settings;
3
4 import com.intellij.openapi.Disposable;
5 import com.intellij.openapi.application.ApplicationManager;
6 import com.intellij.openapi.components.PersistentStateComponent;
7 import com.intellij.openapi.components.State;
8 import com.intellij.openapi.components.Storage;
9 import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager;
10 import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl;
11 import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
12 import com.intellij.openapi.externalSystem.settings.ExternalSystemSettingsListener;
13 import com.intellij.openapi.project.ExternalStorageConfigurationManager;
14 import com.intellij.openapi.project.Project;
15 import com.intellij.openapi.util.Comparing;
16 import com.intellij.util.xmlb.annotations.XCollection;
17 import org.jetbrains.annotations.NotNull;
18 import org.jetbrains.annotations.Nullable;
19 import org.jetbrains.plugins.gradle.config.DelegatingGradleSettingsListenerAdapter;
20
21 import java.util.Objects;
22 import java.util.Set;
23 import java.util.TreeSet;
24
25 /**
26  * Holds shared project-level gradle-related settings (should be kept at the '*.ipr' or under '.idea').
27  *
28  * @author peter
29  */
30 @State(name = "GradleSettings", storages = @Storage("gradle.xml"))
31 public class GradleSettings extends AbstractExternalSystemSettings<GradleSettings, GradleProjectSettings, GradleSettingsListener>
32   implements PersistentStateComponent<GradleSettings.MyState> {
33
34   private boolean isOfflineMode = false;
35
36   public GradleSettings(@NotNull Project project) {
37     super(GradleSettingsListener.TOPIC, project);
38   }
39
40   @NotNull
41   public static GradleSettings getInstance(@NotNull Project project) {
42     return project.getService(GradleSettings.class);
43   }
44
45   @Override
46   public void subscribe(@NotNull ExternalSystemSettingsListener<GradleProjectSettings> listener) {
47     doSubscribe(new DelegatingGradleSettingsListenerAdapter(listener), getProject());
48   }
49
50   @Override
51   public void subscribe(@NotNull ExternalSystemSettingsListener<GradleProjectSettings> listener, @NotNull Disposable parentDisposable) {
52     doSubscribe(new DelegatingGradleSettingsListenerAdapter(listener), parentDisposable);
53   }
54
55   @Override
56   protected void copyExtraSettingsFrom(@NotNull GradleSettings settings) {
57   }
58
59   @Nullable
60   @Override
61   public GradleSettings.MyState getState() {
62     MyState state = new MyState();
63     fillState(state);
64
65     state.setOfflineMode(isOfflineWork());
66
67     return state;
68   }
69
70   @Override
71   public void loadState(@NotNull MyState state) {
72     super.loadState(state);
73
74     setOfflineWork(state.isOfflineMode());
75
76     if (ApplicationManager.getApplication().isUnitTestMode()) {
77       return;
78     }
79
80     GradleSettingsMigration migration = getProject().getService(GradleSettingsMigration.class);
81
82     // When we are opening pre 2019.2 project, we need to import project defaults from the workspace
83     // The migration flag is saved to a separate component to preserve backward and forward compatibility.
84     if (migration.getMigrationVersion() < 1) {
85       migration.setMigrationVersion(1);
86
87       GradleSettingsMigration.LegacyDefaultGradleProjectSettings.MyState legacyProjectDefaults
88         = getProject().getService(GradleSettingsMigration.LegacyDefaultGradleProjectSettings.class).getState();
89       if (legacyProjectDefaults != null) {
90         for (GradleProjectSettings each : getLinkedProjectsSettings()) {
91           if (each.getDirectDelegatedBuild() == null) each.setDelegatedBuild(legacyProjectDefaults.delegatedBuild);
92           if (each.getDirectTestRunner() == null) each.setTestRunner(legacyProjectDefaults.testRunner);
93         }
94       }
95     }
96   }
97
98   /**
99    * @return service directory path (if defined). 'Service directory' is a directory which is used internally by gradle during
100    * calls to the tooling api. E.g. it holds downloaded binaries (dependency jars). We allow to define it because there
101    * is a possible situation when a user wants to configure particular directory to be excluded from anti-virus protection
102    * in order to increase performance
103    */
104   @Nullable
105   public String getServiceDirectoryPath() {
106     return GradleSystemSettings.getInstance().getServiceDirectoryPath();
107   }
108
109   public void setServiceDirectoryPath(@Nullable String newPath) {
110     String myServiceDirectoryPath = GradleSystemSettings.getInstance().getServiceDirectoryPath();
111     if (!Objects.equals(myServiceDirectoryPath, newPath)) {
112       GradleSystemSettings.getInstance().setServiceDirectoryPath(newPath);
113       getPublisher().onServiceDirectoryPathChange(myServiceDirectoryPath, newPath);
114     }
115   }
116
117   @Nullable
118   public String getGradleVmOptions() {
119     return GradleSystemSettings.getInstance().getGradleVmOptions();
120   }
121
122   public void setGradleVmOptions(@Nullable String gradleVmOptions) {
123     String myGradleVmOptions = GradleSystemSettings.getInstance().getGradleVmOptions();
124     if (!Objects.equals(myGradleVmOptions, gradleVmOptions)) {
125       GradleSystemSettings.getInstance().setGradleVmOptions(gradleVmOptions);
126       getPublisher().onGradleVmOptionsChange(myGradleVmOptions, gradleVmOptions);
127     }
128   }
129
130   public boolean isOfflineWork() {
131     return isOfflineMode;
132   }
133
134   public void setOfflineWork(boolean isOfflineMode) {
135     this.isOfflineMode = isOfflineMode;
136   }
137
138   public boolean getStoreProjectFilesExternally() {
139     return ExternalStorageConfigurationManager.getInstance(getProject()).isEnabled();
140   }
141
142   public void setStoreProjectFilesExternally(boolean value) {
143     ExternalProjectsManagerImpl.getInstance(getProject()).setStoreExternally(value);
144   }
145
146   @Override
147   protected void checkSettings(@NotNull GradleProjectSettings old, @NotNull GradleProjectSettings current) {
148     if (!Objects.equals(old.getGradleHome(), current.getGradleHome())) {
149       getPublisher().onGradleHomeChange(old.getGradleHome(), current.getGradleHome(), current.getExternalProjectPath());
150     }
151     if (old.getDistributionType() != current.getDistributionType()) {
152       getPublisher().onGradleDistributionTypeChange(current.getDistributionType(), current.getExternalProjectPath());
153     }
154     if (old.isResolveModulePerSourceSet() != current.isResolveModulePerSourceSet()) {
155       ExternalProjectsManager.getInstance(getProject()).getExternalProjectsWatcher().markDirty(current.getExternalProjectPath());
156     }
157     if (!Comparing.equal(old.getDelegatedBuild(), current.getDelegatedBuild())) {
158       boolean delegatedBuild = GradleProjectSettings.isDelegatedBuildEnabled(getProject(), current.getExternalProjectPath());
159       getPublisher().onBuildDelegationChange(delegatedBuild, current.getExternalProjectPath());
160     }
161     if (!Comparing.equal(old.getTestRunner(), current.getTestRunner())) {
162       TestRunner testRunner = GradleProjectSettings.getTestRunner(getProject(), current.getExternalProjectPath());
163       getPublisher().onTestRunnerChange(testRunner, current.getExternalProjectPath());
164     }
165   }
166
167   public static class MyState implements State<GradleProjectSettings> {
168     private final Set<GradleProjectSettings> myProjectSettings = new TreeSet<>();
169     private boolean isOfflineMode = false;
170
171     @Override
172     @XCollection(elementTypes = {GradleProjectSettings.class})
173     public Set<GradleProjectSettings> getLinkedExternalProjectsSettings() {
174       return myProjectSettings;
175     }
176
177     @Override
178     public void setLinkedExternalProjectsSettings(Set<GradleProjectSettings> settings) {
179       if (settings != null) {
180         myProjectSettings.addAll(settings);
181       }
182     }
183
184     public boolean isOfflineMode() {
185       return isOfflineMode;
186     }
187
188     public void setOfflineMode(boolean isOfflineMode) {
189       this.isOfflineMode = isOfflineMode;
190     }
191   }
192 }