diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTask.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTask.java index 2329fd38e67d..f0ebb53547ad 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTask.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTask.java @@ -43,14 +43,14 @@ public interface ExternalSystemTask { * @param indicator target progress indicator * @param listeners callbacks to be notified on task execution update */ - void cancel(@NotNull ProgressIndicator indicator, @NotNull ExternalSystemTaskNotificationListener... listeners); + boolean cancel(@NotNull ProgressIndicator indicator, @NotNull ExternalSystemTaskNotificationListener... listeners); /** * Cancels current task at the calling thread, i.e. the call to this method blocks. * * @param listeners callbacks to be notified about the task execution update */ - void cancel(@NotNull ExternalSystemTaskNotificationListener... listeners); + boolean cancel(@NotNull ExternalSystemTaskNotificationListener... listeners); /** * Forces current task to refresh {@link #getState() its state}. diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskState.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskState.java index 2df96affc604..09c6a7263a5e 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskState.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/task/ExternalSystemTaskState.java @@ -21,5 +21,9 @@ package com.intellij.openapi.externalSystem.model.task; */ public enum ExternalSystemTaskState { - NOT_STARTED, IN_PROGRESS, FINISHED, FAILED, CANCELING, CANCELED + NOT_STARTED, IN_PROGRESS, FINISHED, FAILED, CANCELING, CANCELED, CANCELLATION_FAILED; + + public boolean isStopped() { + return this == FINISHED || this == FAILED || this == CANCELED; + } } diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java index db186ca1ddca..4edc4a970d06 100644 --- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java +++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/service/project/ExternalSystemProjectResolver.java @@ -35,17 +35,17 @@ public interface ExternalSystemProjectResolvernull as indication that no specific settings are required - * @param listener callback to be notified about the execution + * @param id id of the current 'resolve project info' task + * @param projectPath absolute path to the target external system config file + * @param isPreviewMode Indicates, that an implementation can not provide/resolve any external dependencies. + * Only project dependencies and local file dependencies may included on the modules' classpath. + * And should not include any 'heavy' tasks like not trivial code generations. + * It is supposed to be fast. + * @param settings settings to use for the project resolving; + * null as indication that no specific settings are required + * @param listener callback to be notified about the execution * @return object-level representation of the target external system project; - * null if it's not possible to resolve the project due to the objective reasons + * null if it's not possible to resolve the project due to the objective reasons * @throws ExternalSystemException in case when unexpected exception occurs during project info construction * @throws IllegalArgumentException if given path is invalid * @throws IllegalStateException if it's not possible to resolve target project info @@ -57,5 +57,12 @@ public interface ExternalSystemProjectResolver * That's why that stuff is covered by the current interface, i.e. different implementations are supposed to provide * different 'in process' modes. - * + * * @author Denis Zhdanov * @since 8/9/13 3:21 PM */ @@ -43,18 +43,27 @@ public interface ExternalSystemCommunicationManager { /** * Creates new external system facade for the given arguments. - * - * @param id if for which new facade is to be created - * @param externalSystemId target external system id - * @return newly created facade for the given arguments (if it was possible to create one) - * @throws Exception in case something goes wrong + * + * @param id if for which new facade is to be created + * @param externalSystemId target external system id + * @return newly created facade for the given arguments (if it was possible to create one) + * @throws Exception in case something goes wrong */ @Nullable RemoteExternalSystemFacade acquire(@NotNull String id, @NotNull ProjectSystemId externalSystemId) throws Exception; + /** + * Release resource acquired by the current manager + * + * @param id resource id + * @param externalSystemId target external system id + * @throws Exception in case something goes wrong + */ + void release(@NotNull String id, @NotNull ProjectSystemId externalSystemId) throws Exception; + boolean isAlive(@NotNull RemoteExternalSystemFacade facade); - + /** * Disposes all resources acquired by the current manager. */ diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java index edf4fee1f020..83a010b03620 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/ExternalSystemFacadeManager.java @@ -145,6 +145,11 @@ public class ExternalSystemFacadeManager { } } + public ExternalSystemCommunicationManager getCommunicationManager(@NotNull ProjectSystemId externalSystemId) { + final boolean currentInProcess = ExternalSystemApiUtil.isInProcessMode(externalSystemId); + return currentInProcess ? myInProcessCommunicationManager : myRemoteCommunicationManager; + } + @SuppressWarnings("ConstantConditions") @NotNull private RemoteExternalSystemFacade doGetFacade(@NotNull IntegrationKey key, @NotNull Project project) throws Exception { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/InProcessExternalSystemCommunicationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/InProcessExternalSystemCommunicationManager.java index 40b0163e8a79..74f89957ef6a 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/InProcessExternalSystemCommunicationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/InProcessExternalSystemCommunicationManager.java @@ -48,6 +48,10 @@ public class InProcessExternalSystemCommunicationManager implements ExternalSyst return result; } + @Override + public void release(@NotNull String id, @NotNull ProjectSystemId externalSystemId) throws Exception { + } + @Override public boolean isAlive(@NotNull RemoteExternalSystemFacade facade) { RemoteExternalSystemFacade toCheck = facade; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java index ea9af5a1e1de..47ae760119b3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemCommunicationManager.java @@ -231,6 +231,11 @@ public class RemoteExternalSystemCommunicationManager implements ExternalSystemC return facade; } + @Override + public void release(@NotNull String id, @NotNull ProjectSystemId externalSystemId) throws Exception { + mySupport.release(this, id); + } + @Override public boolean isAlive(@NotNull RemoteExternalSystemFacade facade) { RemoteExternalSystemFacade toCheck = facade; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java index 5a095f740069..350fec62a977 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/RemoteExternalSystemFacade.java @@ -57,7 +57,8 @@ public interface RemoteExternalSystemFacade myState = new AtomicReference(ExternalSystemTaskState.NOT_STARTED); - private final AtomicReference myError = new AtomicReference(); + private final AtomicReference myError = new AtomicReference(); @NotNull private final transient Project myIdeProject; @NotNull private final ExternalSystemTaskId myId; - @NotNull private final ProjectSystemId myExternalSystemId; - @NotNull private final String myExternalProjectPath; + @NotNull private final ProjectSystemId myExternalSystemId; + @NotNull private final String myExternalProjectPath; protected AbstractExternalSystemTask(@NotNull ProjectSystemId id, @NotNull ExternalSystemTaskType type, @NotNull Project project, - @NotNull String externalProjectPath) - { + @NotNull String externalProjectPath) { myExternalSystemId = id; myIdeProject = project; myId = ExternalSystemTaskId.create(id, type, myIdeProject); @@ -67,6 +66,10 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { myState.set(state); } + protected boolean compareAndSetState(@NotNull ExternalSystemTaskState expect, @NotNull ExternalSystemTaskState update) { + return myState.compareAndSet(expect, update); + } + @Override public Throwable getError() { return myError.get(); @@ -114,7 +117,7 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { ls = ArrayUtil.append(listeners, adapter); } else { - ls = new ExternalSystemTaskNotificationListener[] { adapter }; + ls = new ExternalSystemTaskNotificationListener[]{adapter}; } execute(ls); @@ -122,30 +125,35 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { @Override public void execute(@NotNull ExternalSystemTaskNotificationListener... listeners) { + if (!compareAndSetState(ExternalSystemTaskState.NOT_STARTED, ExternalSystemTaskState.IN_PROGRESS)) return; + ExternalSystemProgressNotificationManager progressManager = ServiceManager.getService(ExternalSystemProgressNotificationManager.class); for (ExternalSystemTaskNotificationListener listener : listeners) { progressManager.addNotificationListener(getId(), listener); } + ExternalSystemProcessingManager processingManager = ServiceManager.getService(ExternalSystemProcessingManager.class); try { + processingManager.add(this); doExecute(); + setState(ExternalSystemTaskState.FINISHED); } catch (Throwable e) { setState(ExternalSystemTaskState.FAILED); myError.set(e); LOG.warn(e); - } finally { for (ExternalSystemTaskNotificationListener listener : listeners) { progressManager.removeNotificationListener(listener); } + processingManager.release(getId()); } } protected abstract void doExecute() throws Exception; @Override - public void cancel(@NotNull final ProgressIndicator indicator, @NotNull ExternalSystemTaskNotificationListener... listeners) { + public boolean cancel(@NotNull final ProgressIndicator indicator, @NotNull ExternalSystemTaskNotificationListener... listeners) { indicator.setIndeterminate(true); ExternalSystemTaskNotificationListenerAdapter adapter = new ExternalSystemTaskNotificationListenerAdapter() { @Override @@ -158,23 +166,32 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { ls = ArrayUtil.append(listeners, adapter); } else { - ls = new ExternalSystemTaskNotificationListener[] { adapter }; + ls = new ExternalSystemTaskNotificationListener[]{adapter}; } - cancel(ls); + return cancel(ls); } @Override - public void cancel(@NotNull ExternalSystemTaskNotificationListener... listeners) { + public boolean cancel(@NotNull ExternalSystemTaskNotificationListener... listeners) { + ExternalSystemTaskState currentTaskState = getState(); + if (currentTaskState.isStopped()) return true; + ExternalSystemProgressNotificationManager progressManager = ServiceManager.getService(ExternalSystemProgressNotificationManager.class); for (ExternalSystemTaskNotificationListener listener : listeners) { progressManager.addNotificationListener(getId(), listener); } + + if (!compareAndSetState(currentTaskState, ExternalSystemTaskState.CANCELING)) return false; + + boolean result = false; try { - doCancel(); + result = doCancel(); + setState(result ? ExternalSystemTaskState.CANCELED : ExternalSystemTaskState.CANCELLATION_FAILED); + return result; } catch (Throwable e) { - setState(ExternalSystemTaskState.FAILED); + setState(ExternalSystemTaskState.CANCELLATION_FAILED); myError.set(e); LOG.warn(e); } @@ -183,9 +200,10 @@ public abstract class AbstractExternalSystemTask implements ExternalSystemTask { progressManager.removeNotificationListener(listener); } } + return result; } - protected abstract void doCancel() throws Exception; + protected abstract boolean doCancel() throws Exception; @NotNull diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java index 8b5cb63beb04..0d898cecb2cb 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemExecuteTaskTask.java @@ -19,7 +19,6 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.RemoteExternalSystemFacade; @@ -55,8 +54,7 @@ public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask { @NotNull Project project, @NotNull List tasksToExecute, @Nullable String vmOptions, - @Nullable String debuggerSetup) throws IllegalArgumentException - { + @Nullable String debuggerSetup) throws IllegalArgumentException { super(externalSystemId, ExternalSystemTaskType.EXECUTE_TASK, project, getLinkedExternalProjectPath(tasksToExecute)); myTasksToExecute = tasksToExecute; myVmOptions = vmOptions; @@ -80,7 +78,8 @@ public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask { "but they are not (at least two different projects detected - '%s' and '%s'). Tasks: %s", result, task.getLinkedExternalProjectPath(), - tasks)); + tasks + )); } } assert result != null; @@ -98,26 +97,15 @@ public class ExternalSystemExecuteTaskTask extends AbstractExternalSystemTask { RemoteExternalSystemTaskManager taskManager = facade.getTaskManager(); List taskNames = ContainerUtilRt.map2List(myTasksToExecute, MAPPER); - setState(ExternalSystemTaskState.IN_PROGRESS); - try { - taskManager.executeTasks(getId(), taskNames, getExternalProjectPath(), settings, myVmOptions, myDebuggerSetup); - } - finally { - setState(ExternalSystemTaskState.FINISHED); - } + taskManager.executeTasks(getId(), taskNames, getExternalProjectPath(), settings, myVmOptions, myDebuggerSetup); } @Override - protected void doCancel() throws Exception { + protected boolean doCancel() throws Exception { final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); RemoteExternalSystemFacade facade = manager.getFacade(getIdeProject(), getExternalProjectPath(), getExternalSystemId()); RemoteExternalSystemTaskManager taskManager = facade.getTaskManager(); - setState(ExternalSystemTaskState.CANCELING); - try { - taskManager.cancelTask(getId()); - } - finally { - setState(ExternalSystemTaskState.CANCELED); - } + + return taskManager.cancelTask(getId()); } } diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java index 999b201c07bb..dc9f6ef6334d 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemProcessingManager.java @@ -3,17 +3,18 @@ package com.intellij.openapi.externalSystem.service.internal; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.externalSystem.model.ProjectSystemId; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationEvent; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; +import com.intellij.openapi.externalSystem.model.task.*; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.util.Alarm; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtilRt; +import com.intellij.util.containers.Convertor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.concurrent.ConcurrentMap; @@ -45,6 +46,7 @@ public class ExternalSystemProcessingManager implements ExternalSystemTaskNotifi private static final long TOO_LONG_EXECUTION_MS = TimeUnit.SECONDS.toMillis(10); @NotNull private final ConcurrentMap myTasksInProgress = ContainerUtil.newConcurrentMap(); + @NotNull private final ConcurrentMap myTasksDetails = ContainerUtil.newConcurrentMap(); @NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD); @NotNull private final ExternalSystemFacadeManager myFacadeManager; @@ -85,6 +87,32 @@ public class ExternalSystemProcessingManager implements ExternalSystemTaskNotifi return false; } + @Nullable + public ExternalSystemTask findTask(@NotNull ExternalSystemTaskType type, + @NotNull ProjectSystemId projectSystemId, + @NotNull final String externalProjectPath) { + for(ExternalSystemTask task : myTasksDetails.values()) { + if(task instanceof AbstractExternalSystemTask) { + AbstractExternalSystemTask externalSystemTask = (AbstractExternalSystemTask)task; + if(externalSystemTask.getId().getType() == type && + externalSystemTask.getExternalSystemId().getId().equals(projectSystemId.getId()) && + externalSystemTask.getExternalProjectPath().equals(externalProjectPath)){ + return task; + } + } + } + + return null; + } + + public void add(@NotNull ExternalSystemTask task) { + myTasksDetails.put(task.getId(), task); + } + + public void release(@NotNull ExternalSystemTaskId id) { + myTasksDetails.remove(id); + } + @Override public void onQueued(@NotNull ExternalSystemTaskId id) { myTasksInProgress.put(id, System.currentTimeMillis() + TOO_LONG_EXECUTION_MS); diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java index fe0d5466dfa2..42108cb1532e 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemResolveProjectTask.java @@ -5,7 +5,6 @@ import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.ProjectData; import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings; -import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; import com.intellij.openapi.externalSystem.service.ExternalSystemFacadeManager; import com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolver; @@ -19,7 +18,7 @@ import java.util.concurrent.atomic.AtomicReference; /** * Thread-safe. - * + * * @author Denis Zhdanov * @since 1/24/12 7:21 AM */ @@ -27,14 +26,13 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask private final AtomicReference> myExternalProject = new AtomicReference>(); - @NotNull private final String myProjectPath; - private final boolean myIsPreviewMode; + @NotNull private final String myProjectPath; + private final boolean myIsPreviewMode; public ExternalSystemResolveProjectTask(@NotNull ProjectSystemId externalSystemId, @NotNull Project project, @NotNull String projectPath, - boolean isPreviewMode) - { + boolean isPreviewMode) { super(externalSystemId, ExternalSystemTaskType.RESOLVE_PROJECT, project, projectPath); myProjectPath = projectPath; myIsPreviewMode = isPreviewMode; @@ -45,35 +43,22 @@ public class ExternalSystemResolveProjectTask extends AbstractExternalSystemTask final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); Project ideProject = getIdeProject(); RemoteExternalSystemProjectResolver resolver = manager.getFacade(ideProject, myProjectPath, getExternalSystemId()).getResolver(); - - setState(ExternalSystemTaskState.IN_PROGRESS); - try { - ExternalSystemExecutionSettings settings = ExternalSystemApiUtil - .getExecutionSettings(ideProject, myProjectPath, getExternalSystemId()); - DataNode project = resolver.resolveProjectInfo(getId(), myProjectPath, myIsPreviewMode, settings); + ExternalSystemExecutionSettings settings = ExternalSystemApiUtil.getExecutionSettings(ideProject, myProjectPath, getExternalSystemId()); - if (project == null) { - return; - } - myExternalProject.set(project); - } - finally { - setState(ExternalSystemTaskState.FINISHED); + DataNode project = resolver.resolveProjectInfo(getId(), myProjectPath, myIsPreviewMode, settings); + + if (project == null) { + return; } + myExternalProject.set(project); } - protected void doCancel() throws Exception { + protected boolean doCancel() throws Exception { final ExternalSystemFacadeManager manager = ServiceManager.getService(ExternalSystemFacadeManager.class); Project ideProject = getIdeProject(); RemoteExternalSystemProjectResolver resolver = manager.getFacade(ideProject, myProjectPath, getExternalSystemId()).getResolver(); - setState(ExternalSystemTaskState.CANCELING); - try { - resolver.cancelTask(getId()); - } - finally { - setState(ExternalSystemTaskState.CANCELED); - } + return resolver.cancelTask(getId()); } @Nullable diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java index 7ecc0c6028f9..56a13de14924 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/internal/ExternalSystemTaskAware.java @@ -35,7 +35,7 @@ public interface ExternalSystemTaskAware { * false otherwise * @throws RemoteException as required by RMI */ - void cancelTask(@NotNull ExternalSystemTaskId id) throws RemoteException; + boolean cancelTask(@NotNull ExternalSystemTaskId id) throws RemoteException; /** * Allows to ask current service for all tasks being executed at the moment. diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java index 15300f060792..bc7cb8ddab76 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/autoimport/ExternalSystemAutoImporter.java @@ -25,6 +25,10 @@ import com.intellij.openapi.externalSystem.ExternalSystemManager; import com.intellij.openapi.externalSystem.model.DataNode; import com.intellij.openapi.externalSystem.model.ProjectSystemId; import com.intellij.openapi.externalSystem.model.project.ProjectData; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTask; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskState; +import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType; +import com.intellij.openapi.externalSystem.service.internal.ExternalSystemProcessingManager; import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback; import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager; import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings; @@ -51,7 +55,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -332,11 +336,29 @@ public class ExternalSystemAutoImporter implements BulkFileListener, DocumentLis documentLock.unlock(); } + boolean scheduleRefresh = false; + ExternalSystemProcessingManager processingManager = ServiceManager.getService(ExternalSystemProcessingManager.class); for (Map.Entry> entry : copy.entrySet()) { for (String path : entry.getValue()) { - ExternalSystemUtil.refreshProject(myProject, entry.getKey(), path, myRefreshCallback, false, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false); + final ExternalSystemTask resolveTask = processingManager.findTask(ExternalSystemTaskType.RESOLVE_PROJECT, entry.getKey(), path); + final ExternalSystemTaskState taskState = resolveTask == null ? null : resolveTask.getState(); + if (taskState == null || taskState.isStopped() || + (taskState == ExternalSystemTaskState.IN_PROGRESS && resolveTask.cancel())) { + ExternalSystemUtil.refreshProject( + myProject, entry.getKey(), path, myRefreshCallback, false, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false); + } + else if (taskState != ExternalSystemTaskState.NOT_STARTED) { + // re-schedule to wait for the project import task end + scheduleRefresh = true; + addPath(entry.getKey(), path); + } } } + + if (scheduleRefresh) { + myVfsAlarm.cancelAllRequests(); + myVfsAlarm.addRequest(myFilesRequest, ExternalSystemConstants.AUTO_IMPORT_DELAY_MILLIS); + } } private static class MyEntry { diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolver.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolver.java index 2e5ce6469684..818bbdb91ba9 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolver.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/remote/RemoteExternalSystemProjectResolver.java @@ -65,7 +65,8 @@ public interface RemoteExternalSystemProjectResolver doResolveProjectInfo(@NotNull final ProjectResolverContext resolverCtx, @NotNull final GradleProjectResolverExtension projectResolverChain) diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java index 757f04757a25..0555f3111303 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java @@ -96,17 +96,18 @@ public class GradleTaskManager implements ExternalSystemTaskManager