diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index 7afc8950dde5..46b953b6956c 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -53,7 +53,6 @@
-
org.jetbrains.plugins.gradle.notification.GradleConfigNotificationManager
+
+ org.jetbrains.plugins.gradle.task.GradleTaskManager
+
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java
index 52007519dc49..e47bc21333b3 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.gradle.action;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
@@ -32,7 +31,7 @@ public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectActio
@Override
protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) {
boolean enabled = false;
- final GradleTaskManager taskManager = ServiceManager.getService(GradleTaskManager.class);
+ final GradleTaskManager taskManager = project.getComponent(GradleTaskManager.class);
if (taskManager != null) {
enabled = !taskManager.hasTaskOfTypeInProgress(GradleTaskType.RESOLVE_PROJECT);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
index 5c42b3763ba2..7416ae2ec650 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleConfigurable.java
@@ -37,6 +37,8 @@ import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.concurrent.TimeUnit;
@@ -117,6 +119,22 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
}
}
};
+ myComponent.addPropertyChangeListener(new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (!"ancestor".equals(evt.getPropertyName())) {
+ return;
+ }
+
+ // Configure the balloon to show on initial configurable drawing.
+ myShowBalloonIfNecessary = evt.getNewValue() != null && evt.getOldValue() == null;
+
+ if (evt.getNewValue() == null && evt.getOldValue() != null) {
+ // Cancel delayed balloons when the configurable is hidden.
+ myAlarm.cancelAllRequests();
+ }
+ }
+ });
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
@@ -151,7 +169,6 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
@Override
public boolean isModified() {
- myShowBalloonIfNecessary = true;
if (!myPathManuallyModified) {
return false;
}
@@ -169,17 +186,25 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
useNormalColorForPath();
String path = myGradleHomeComponent.getPath();
GradleSettings.applyGradleHome(path, myProject);
-
- // There is a possible case that user defines gradle home for particular open project. We want to apply that value
- // to the default project as well if it's still non-defined.
- Project defaultProject = ProjectManager.getInstance().getDefaultProject();
- if (defaultProject == myProject) {
+
+ if (isValidGradleHome(path)) {
+ myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_CORRECT;
+ // There is a possible case that user defines gradle home for particular open project. We want to apply that value
+ // to the default project as well if it's still non-defined.
+ Project defaultProject = ProjectManager.getInstance().getDefaultProject();
+ if (defaultProject != myProject && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
+ GradleSettings.applyGradleHome(path, defaultProject);
+ }
return;
}
- if (isValidGradleHome(path) && !isValidGradleHome(GradleSettings.getInstance(defaultProject).getGradleHome())) {
- GradleSettings.applyGradleHome(path, defaultProject);
- }
+ if (StringUtil.isEmpty(path)) {
+ myGradleHomeSettingType = GradleHomeSettingType.UNKNOWN;
+ }
+ else {
+ myGradleHomeSettingType = GradleHomeSettingType.EXPLICIT_INCORRECT;
+ new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
+ }
}
private boolean isValidGradleHome(@Nullable String path) {
@@ -203,7 +228,7 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
GradleHomeSettingType.EXPLICIT_CORRECT :
GradleHomeSettingType.EXPLICIT_INCORRECT;
if (myGradleHomeSettingType == GradleHomeSettingType.EXPLICIT_INCORRECT) {
- new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType).run();
+ new DelayedBalloonInfo(MessageType.ERROR, myGradleHomeSettingType, 0).run();
}
else {
myAlarm.cancelAllRequests();
@@ -283,9 +308,13 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
private final long myTriggerTime;
DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType) {
+ this(messageType, settingType, BALLOON_DELAY_MILLIS);
+ }
+
+ DelayedBalloonInfo(@NotNull MessageType messageType, @NotNull GradleHomeSettingType settingType, long delayMillis) {
myMessageType = messageType;
myText = settingType.getDescription();
- myTriggerTime = System.currentTimeMillis() + BALLOON_DELAY_MILLIS;
+ myTriggerTime = System.currentTimeMillis() + delayMillis;
}
@Override
@@ -296,11 +325,15 @@ public class GradleConfigurable implements SearchableConfigurable, Configurable.
myAlarm.addRequest(this, diff);
return;
}
- if (myGradleHomeComponent == null || !myGradleHomeComponent.getPathComponent().isShowing()) {
+ if (myGradleHomeComponent == null) {
myAlarm.cancelAllRequests();
myAlarm.addRequest(this, 200);
return;
}
+ if (!myGradleHomeComponent.getPathComponent().isShowing()) {
+ // Don't schedule the balloon if the configurable is hidden.
+ return;
+ }
GradleUtil.showBalloon(myGradleHomeComponent.getPathComponent(), myMessageType, myText);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
index 1c192c1cef84..edc0ea2d1184 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleModulesImporter.java
@@ -338,7 +338,7 @@ public class GradleModulesImporter {
public void run(@NotNull final ProgressIndicator indicator) {
GradleResolveProjectTask task = new GradleResolveProjectTask(intellijProject, gradleProjectPath, true);
task.execute(indicator);
- GradleProject projectWithResolvedLibraries = task.getProject();
+ GradleProject projectWithResolvedLibraries = task.getGradleProject();
gradleProjectRef.set(projectWithResolvedLibraries);
ApplicationManager.getApplication().invokeLater(setupExternalDependenciesTask, ModalityState.NON_MODAL);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java
index beafc16f69e6..a54979f44b8d 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java
@@ -14,11 +14,15 @@ import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.rmi.RemoteProcessSupport;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.*;
import com.intellij.openapi.roots.DependencyScope;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.text.StringUtil;
@@ -27,8 +31,10 @@ import com.intellij.psi.PsiBundle;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
import com.intellij.util.SystemProperties;
+import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl;
import org.jetbrains.plugins.gradle.remote.impl.GradleApiFacadeImpl;
@@ -49,8 +55,8 @@ import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
/**
* Entry point to work with remote {@link GradleApiFacade}.
@@ -62,15 +68,19 @@ import java.util.concurrent.atomic.AtomicReference;
*/
public class GradleApiFacadeManager {
+ private static final Pair NULL_VALUE = Pair.empty();
+
private static final String REMOTE_PROCESS_TTL_IN_MS_KEY = "gradle.remote.process.ttl.ms";
private static final String MAIN_CLASS_NAME = GradleApiFacadeImpl.class.getName();
private static final int REMOTE_FAIL_RECOVERY_ATTEMPTS_NUMBER = 3;
- private final AtomicReference> myFacade
- = new AtomicReference>();
- private final AtomicReference myExportedProgressManager
- = new AtomicReference();
+ private final ConcurrentMap myFacadeWrappers
+ = new ConcurrentWeakHashMap();
+ private final ConcurrentMap myRemoteNotificationManagers
+ = new ConcurrentWeakHashMap();
+ private final ConcurrentMap> myRemoteFacades
+ = new ConcurrentWeakHashMap>();
@NotNull private final GradleLibraryManager myGradleLibraryManager;
@NotNull private final GradleProgressNotificationManagerImpl myProgressManager;
@@ -78,13 +88,12 @@ public class GradleApiFacadeManager {
// Please note that we don't use RemoteGradleProcessSettings as the 'Configuration' type parameter here because we need
// to apply the settings to the newly created process. I.e. every time new process is created we need to call
// 'GradleApiFacade.applySettings()'. So, we need to hold reference to the last returned 'GradleApiFacade' stub anyway.
- private final RemoteProcessSupport