diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index ff4374eb52a2..df0d5da1f7de 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -49,6 +49,7 @@
+
org.jetbrains.plugins.gradle.sync.GradleProjectStructureHelper
+
+ org.jetbrains.plugins.gradle.sync.GradleProjectStructureChangesDetector
+
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
index bbd49d974a04..701da05b145b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/AbstractGradleLinkedProjectAction.java
@@ -2,6 +2,7 @@ package org.jetbrains.plugins.gradle.action;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -21,13 +22,13 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction {
@Override
public void update(AnActionEvent e) {
- final String path = getLinkedProjectPath(e.getDataContext());
- final boolean visible = path != null;
+ final Pair pair = deriveProjects(e.getDataContext());
+ final boolean visible = pair != null;
e.getPresentation().setVisible(visible);
if (!visible) {
return;
}
- doUpdate(e.getPresentation(), path);
+ doUpdate(e.getPresentation(), pair.first, pair.second);
}
@Override
@@ -36,16 +37,16 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction {
if (project == null) {
return;
}
- final String path = getLinkedProjectPath(e.getDataContext());
- if (path == null) {
+ final Pair pair = deriveProjects(e.getDataContext());
+ if (pair == null) {
e.getPresentation().setVisible(false);
return;
}
- doActionPerformed(project, path);
+ doActionPerformed(project, pair.second);
}
@Nullable
- protected static String getLinkedProjectPath(@Nullable DataContext context) {
+ private static Pair deriveProjects(@Nullable DataContext context) {
if (context == null) {
return null;
}
@@ -56,9 +57,12 @@ public abstract class AbstractGradleLinkedProjectAction extends AnAction {
}
final String path = GradleSettings.getInstance(project).LINKED_PROJECT_FILE_PATH;
- return (StringUtil.isEmpty(path) || !new File(path).isFile()) ? null : path;
+ if (StringUtil.isEmpty(path) || !new File(path).isFile()) {
+ return null;
+ }
+ return new Pair(project, path);
}
- protected abstract void doUpdate(@NotNull Presentation presentation, @NotNull String linkedProjectPath);
+ protected abstract void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath);
protected abstract void doActionPerformed(@NotNull Project project, @NotNull String linkedProjectPath);
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleOpenScriptAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleOpenScriptAction.java
index f010e59ebde8..79f35b14803a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleOpenScriptAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleOpenScriptAction.java
@@ -1,7 +1,5 @@
package org.jetbrains.plugins.gradle.action;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -32,7 +30,7 @@ public class GradleOpenScriptAction extends AbstractGradleLinkedProjectAction im
}
@Override
- protected void doUpdate(@NotNull Presentation presentation, @NotNull String linkedProjectPath) {
+ protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) {
}
@Override
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 17fa3a0fbc4e..087e1706733b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/action/GradleRefreshProjectAction.java
@@ -1,17 +1,16 @@
package org.jetbrains.plugins.gradle.action;
+import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.config.GradleSettings;
-import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
+import org.jetbrains.plugins.gradle.task.GradleTaskManager;
+import org.jetbrains.plugins.gradle.task.GradleTaskType;
import org.jetbrains.plugins.gradle.util.GradleBundle;
-
-import java.util.concurrent.atomic.AtomicBoolean;
+import org.jetbrains.plugins.gradle.util.GradleUtil;
/**
* Forces the 'gradle' plugin to retrieve the most up-to-date info about the
@@ -21,34 +20,25 @@ import java.util.concurrent.atomic.AtomicBoolean;
* @author Denis Zhdanov
* @since 1/23/12 3:48 PM
*/
-public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectAction implements DumbAware {
+public class GradleRefreshProjectAction extends AbstractGradleLinkedProjectAction implements DumbAware, AnAction.TransparentUpdate {
- private final AtomicBoolean myInProgress = new AtomicBoolean();
-
public GradleRefreshProjectAction() {
getTemplatePresentation().setText(GradleBundle.message("gradle.action.refresh.project.text"));
getTemplatePresentation().setDescription(GradleBundle.message("gradle.action.refresh.project.description"));
}
@Override
- protected void doUpdate(@NotNull Presentation presentation, @NotNull String linkedProjectPath) {
- presentation.setEnabled(!myInProgress.get());
+ protected void doUpdate(@NotNull Presentation presentation, @NotNull Project project, @NotNull String linkedProjectPath) {
+ boolean enabled = false;
+ final GradleTaskManager taskManager = ServiceManager.getService(GradleTaskManager.class);
+ if (taskManager != null) {
+ enabled = !taskManager.hasTaskOfTypeInProgress(GradleTaskType.RESOLVE_PROJECT);
+ }
+ presentation.setEnabled(enabled);
}
@Override
protected void doActionPerformed(@NotNull final Project project, @NotNull final String linkedProjectPath) {
- myInProgress.set(true);
- ProgressManager.getInstance().run(new Task.Backgroundable(project, GradleBundle.message("gradle.sync.progress.text")) {
- @Override
- public void run(@NotNull final ProgressIndicator indicator) {
- try {
- GradleResolveProjectTask task = new GradleResolveProjectTask(project, linkedProjectPath, true);
- task.execute(indicator);
- }
- finally {
- myInProgress.set(false);
- }
- }
- });
+ GradleUtil.refreshProject(project);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
index d8a5a8d4a29c..760166cb0194 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/importing/GradleProjectImportBuilder.java
@@ -1,14 +1,10 @@
package org.jetbrains.plugins.gradle.importing;
-import com.intellij.execution.rmi.RemoteUtil;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.projectRoots.JavaSdk;
@@ -17,7 +13,6 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
import com.intellij.projectImport.ProjectImportBuilder;
import org.jetbrains.annotations.NotNull;
@@ -26,11 +21,9 @@ import org.jetbrains.plugins.gradle.config.GradleSettings;
import org.jetbrains.plugins.gradle.model.GradleEntity;
import org.jetbrains.plugins.gradle.model.GradleModule;
import org.jetbrains.plugins.gradle.model.GradleProject;
-import org.jetbrains.plugins.gradle.remote.GradleApiException;
-import org.jetbrains.plugins.gradle.task.GradleResolveProjectTask;
import org.jetbrains.plugins.gradle.ui.GradleIcons;
import org.jetbrains.plugins.gradle.util.GradleBundle;
-import org.jetbrains.plugins.gradle.util.GradleLog;
+import org.jetbrains.plugins.gradle.util.GradleUtil;
import javax.swing.*;
import java.io.File;
@@ -156,38 +149,7 @@ public class GradleProjectImportBuilder extends ProjectImportBuilder errorReason = new Ref();
try {
final Project project = getProject(wizardContext);
- ProgressManager.getInstance().run(new Task.Modal(project, GradleBundle.message("gradle.import.progress.text"), true) {
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
- @Override
- public void run(@NotNull final ProgressIndicator indicator) {
- GradleResolveProjectTask task = new GradleResolveProjectTask(project, myProjectFile.getAbsolutePath(), false);
- task.execute(indicator);
- myGradleProject = task.getProject();
- if (myGradleProject != null) {
- return;
- }
- final Throwable error = task.getError();
- if (error == null) {
- return;
- }
- Throwable unwrapped = RemoteUtil.unwrap(error);
- String reason = unwrapped.getLocalizedMessage();
- if (!StringUtil.isEmpty(reason)) {
- errorReason.set(reason);
- }
- if (unwrapped.getClass() == NoClassDefFoundError.class) {
- errorReason.set(GradleBundle.message("gradle.import.text.incomplete.tooling.api"));
- }
- else if (unwrapped.getClass() == GradleApiException.class) {
- GradleLog.LOG.warn("Can't resolve gradle project. Reason: gradle api threw an exception:\n"
- + ((GradleApiException)unwrapped).getOriginalReason()
- );
- }
- else {
- GradleLog.LOG.warn("Can't resolve gradle project", unwrapped);
- }
- }
- });
+ myGradleProject = GradleUtil.refreshProject(project, myProjectFile.getAbsolutePath(), errorReason, false, true);
}
catch (IllegalArgumentException e) {
throw new ConfigurationException(e.getMessage(), GradleBundle.message("gradle.import.text.error.cannot.parse.project"));
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManager.java
index 7c134a94f968..a048f1cead9f 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManager.java
@@ -9,6 +9,15 @@ import org.jetbrains.plugins.gradle.task.GradleTaskId;
*/
public interface GradleProgressNotificationManager {
+ /**
+ * Allows to register given listener to listen events from all tasks.
+ *
+ * @param listener listener to register
+ * @return true if given listener was not registered before for the given key;
+ * false otherwise
+ */
+ boolean addNotificationListener(@NotNull GradleTaskNotificationListener listener);
+
/**
* Allows to register given listener within the current manager for listening events from the task with the target id.
*
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManagerImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManagerImpl.java
index 80787d206f06..0eb9d5570ce4 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManagerImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleProgressNotificationManagerImpl.java
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.remote.RemoteGradleProgressNotificationManager;
import org.jetbrains.plugins.gradle.task.GradleTaskId;
+import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
@@ -19,9 +20,15 @@ public class GradleProgressNotificationManagerImpl extends RemoteObject
implements GradleProgressNotificationManager, RemoteGradleProgressNotificationManager
{
- private final ConcurrentMap> myListeners
+ private final ConcurrentMap/* EMPTY_SET as a sign of 'all ids' */> myListeners
= new ConcurrentHashMap>();
+ @Override
+ public boolean addNotificationListener(@NotNull GradleTaskNotificationListener listener) {
+ Set dummy = Collections.emptySet();
+ return myListeners.put(listener, dummy) == null;
+ }
+
@Override
public boolean addNotificationListener(@NotNull GradleTaskId taskId, @NotNull GradleTaskNotificationListener listener) {
Set ids = null;
@@ -41,10 +48,22 @@ public class GradleProgressNotificationManagerImpl extends RemoteObject
return myListeners.remove(listener) != null;
}
+ @Override
+ public void onQueued(@NotNull GradleTaskId id) {
+ for (Map.Entry> entry : myListeners.entrySet()) {
+ final Set ids = entry.getValue();
+ if (Collections.EMPTY_SET == ids || ids.contains(id)) {
+ entry.getKey().onQueued(id);
+ }
+ }
+
+ }
+
@Override
public void onStart(@NotNull GradleTaskId id) {
for (Map.Entry> entry : myListeners.entrySet()) {
- if (entry.getValue().contains(id)) {
+ final Set ids = entry.getValue();
+ if (Collections.EMPTY_SET == ids || ids.contains(id)) {
entry.getKey().onStart(id);
}
}
@@ -53,7 +72,8 @@ public class GradleProgressNotificationManagerImpl extends RemoteObject
@Override
public void onStatusChange(@NotNull GradleTaskNotificationEvent event) {
for (Map.Entry> entry : myListeners.entrySet()) {
- if (entry.getValue().contains(event.getId())) {
+ final Set ids = entry.getValue();
+ if (Collections.EMPTY_SET == ids || ids.contains(event.getId())) {
entry.getKey().onStatusChange(event);
}
}
@@ -62,7 +82,8 @@ public class GradleProgressNotificationManagerImpl extends RemoteObject
@Override
public void onEnd(@NotNull GradleTaskId id) {
for (Map.Entry> entry : myListeners.entrySet()) {
- if (entry.getValue().contains(id)) {
+ final Set ids = entry.getValue();
+ if (Collections.EMPTY_SET == ids || ids.contains(id)) {
entry.getKey().onEnd(id);
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListener.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListener.java
index 1b4bda67e8ec..ba4a73fee1fa 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListener.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListener.java
@@ -11,6 +11,16 @@ import org.jetbrains.plugins.gradle.task.GradleTaskId;
*/
public interface GradleTaskNotificationListener {
+ /**
+ * Notifies that task with the given id is queued for the execution.
+ *
+ * 'Queued' here means that intellij process-local codebase receives request to execute the target task and even has not been
+ * sent it to the slave gradle api process.
+ *
+ * @param id target task's id
+ */
+ void onQueued(@NotNull GradleTaskId id);
+
/**
* Notifies that task with the given id is about to be started.
*
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListenerAdapter.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListenerAdapter.java
index a5ff4965a90d..c2ee8ee511b9 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListenerAdapter.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/notification/GradleTaskNotificationListenerAdapter.java
@@ -8,6 +8,11 @@ import org.jetbrains.plugins.gradle.task.GradleTaskId;
* @since 11/10/11 12:18 PM
*/
public class GradleTaskNotificationListenerAdapter implements GradleTaskNotificationListener {
+
+ @Override
+ public void onQueued(@NotNull GradleTaskId id) {
+ }
+
@Override
public void onStart(@NotNull GradleTaskId id) {
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacade.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacade.java
index d2d5dc0e3072..2955f9e3961c 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacade.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacade.java
@@ -1,12 +1,10 @@
package org.jetbrains.plugins.gradle.remote;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.gradle.task.GradleTaskId;
-import org.jetbrains.plugins.gradle.task.GradleTaskType;
+import org.jetbrains.plugins.gradle.task.GradleTaskAware;
import java.rmi.Remote;
import java.rmi.RemoteException;
-import java.util.Collection;
/**
* Serves as a facade for working with
@@ -18,7 +16,7 @@ import java.util.Collection;
* @author Denis Zhdanov
* @since 8/8/11 10:52 AM
*/
-public interface GradleApiFacade extends Remote {
+public interface GradleApiFacade extends Remote, GradleTaskAware {
/**
* Exposes 'resolve gradle project' service that works at another process.
@@ -45,23 +43,4 @@ public interface GradleApiFacade extends Remote {
* @throws RemoteException in case of unexpected I/O exception during processing
*/
void applyProgressManager(@NotNull RemoteGradleProgressNotificationManager progressManager) throws RemoteException;
-
- /**
- * Asks remote gradle process to check if a task with the given id is being executed right now.
- *
- * @param id target task's id
- * @return true if a task with the given id is executed at the moment; false otherwise
- * @throws RemoteException in case of unexpected I/O exception during processing
- */
- boolean isTaskInProgress(@NotNull GradleTaskId id) throws RemoteException;
-
- /**
- * Allows to ask remote gradle process for the ids of the tasks with the given type being executed now.
- *
- * @param type target task type
- * @return ids of the tasks of the target type being executed at the moment (if any)
- * @throws RemoteException in case of unexpected I/O exception during processing
- */
- @NotNull
- Collection getTasksInProgress(@NotNull GradleTaskType type) throws RemoteException;
}
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 02a42690d19f..8972c627d369 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/remote/GradleApiFacadeManager.java
@@ -31,7 +31,9 @@ import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManager;
+import org.jetbrains.plugins.gradle.notification.GradleProgressNotificationManagerImpl;
import org.jetbrains.plugins.gradle.remote.impl.GradleApiFacadeImpl;
+import org.jetbrains.plugins.gradle.remote.wrapper.GradleApiFacadeWrapper;
import org.jetbrains.plugins.gradle.util.GradleBundle;
import org.jetbrains.plugins.gradle.util.GradleLibraryManager;
import org.jetbrains.plugins.gradle.util.GradleLog;
@@ -69,8 +71,8 @@ public class GradleApiFacadeManager {
private final AtomicReference myExportedProgressManager
= new AtomicReference();
- private final GradleLibraryManager myGradleLibraryManager;
- private final RemoteGradleProgressNotificationManager myProgressManager;
+ @NotNull private final GradleLibraryManager myGradleLibraryManager;
+ @NotNull private final GradleProgressNotificationManagerImpl myProgressManager;
// 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
@@ -80,7 +82,7 @@ public class GradleApiFacadeManager {
public GradleApiFacadeManager(@NotNull GradleLibraryManager gradleLibraryManager, @NotNull GradleProgressNotificationManager manager) {
myGradleLibraryManager = gradleLibraryManager;
- myProgressManager = (RemoteGradleProgressNotificationManager)manager;
+ myProgressManager = (GradleProgressNotificationManagerImpl)manager;
mySupport = new RemoteProcessSupport