@Override
  public void compileAndRun(
      @NotNull final Runnable startRunnable,
      @NotNull final ExecutionEnvironment environment,
      @Nullable final RunProfileState state,
      @Nullable final Runnable onCancelRunnable) {
    long id = environment.getExecutionId();
    if (id == 0) {
      id = environment.assignNewExecutionId();
    }

    RunProfile profile = environment.getRunProfile();
    if (!(profile instanceof RunConfiguration)) {
      startRunnable.run();
      return;
    }

    final RunConfiguration runConfiguration = (RunConfiguration) profile;
    final List<BeforeRunTask> beforeRunTasks =
        RunManagerEx.getInstanceEx(myProject).getBeforeRunTasks(runConfiguration);
    if (beforeRunTasks.isEmpty()) {
      startRunnable.run();
    } else {
      DataContext context = environment.getDataContext();
      final DataContext projectContext =
          context != null ? context : SimpleDataContext.getProjectContext(myProject);
      final long finalId = id;
      final Long executionSessionId = new Long(id);
      ApplicationManager.getApplication()
          .executeOnPooledThread(
              () -> {
                for (BeforeRunTask task : beforeRunTasks) {
                  if (myProject.isDisposed()) {
                    return;
                  }
                  @SuppressWarnings("unchecked")
                  BeforeRunTaskProvider<BeforeRunTask> provider =
                      BeforeRunTaskProvider.getProvider(myProject, task.getProviderId());
                  if (provider == null) {
                    LOG.warn(
                        "Cannot find BeforeRunTaskProvider for id='" + task.getProviderId() + "'");
                    continue;
                  }
                  ExecutionEnvironment taskEnvironment =
                      new ExecutionEnvironmentBuilder(environment).contentToReuse(null).build();
                  taskEnvironment.setExecutionId(finalId);
                  EXECUTION_SESSION_ID_KEY.set(taskEnvironment, executionSessionId);
                  if (!provider.executeTask(
                      projectContext, runConfiguration, taskEnvironment, task)) {
                    if (onCancelRunnable != null) {
                      SwingUtilities.invokeLater(onCancelRunnable);
                    }
                    return;
                  }
                }

                doRun(environment, startRunnable);
              });
    }
  }
  @Override
  public void startRunProfile(
      @NotNull final RunProfileStarter starter,
      @NotNull final RunProfileState state,
      @NotNull final ExecutionEnvironment environment) {
    final Project project = environment.getProject();
    RunContentDescriptor reuseContent = getContentManager().getReuseContent(environment);
    if (reuseContent != null) {
      reuseContent.setExecutionId(environment.getExecutionId());
      environment.setContentToReuse(reuseContent);
    }

    final Executor executor = environment.getExecutor();
    project
        .getMessageBus()
        .syncPublisher(EXECUTION_TOPIC)
        .processStartScheduled(executor.getId(), environment);

    Runnable startRunnable;
    startRunnable =
        () -> {
          if (project.isDisposed()) {
            return;
          }

          RunProfile profile = environment.getRunProfile();
          boolean started = false;
          try {
            project
                .getMessageBus()
                .syncPublisher(EXECUTION_TOPIC)
                .processStarting(executor.getId(), environment);

            final RunContentDescriptor descriptor = starter.execute(state, environment);
            if (descriptor != null) {
              final Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor>
                  trinity =
                      Trinity.create(
                          descriptor, environment.getRunnerAndConfigurationSettings(), executor);
              myRunningConfigurations.add(trinity);
              Disposer.register(descriptor, () -> myRunningConfigurations.remove(trinity));
              getContentManager()
                  .showRunContent(executor, descriptor, environment.getContentToReuse());
              final ProcessHandler processHandler = descriptor.getProcessHandler();
              if (processHandler != null) {
                if (!processHandler.isStartNotified()) {
                  processHandler.startNotify();
                }
                project
                    .getMessageBus()
                    .syncPublisher(EXECUTION_TOPIC)
                    .processStarted(executor.getId(), environment, processHandler);
                started = true;

                ProcessExecutionListener listener =
                    new ProcessExecutionListener(
                        project, executor.getId(), environment, processHandler, descriptor);
                processHandler.addProcessListener(listener);

                // Since we cannot guarantee that the listener is added before process handled is
                // start notified,
                // we have to make sure the process termination events are delivered to the clients.
                // Here we check the current process state and manually deliver events, while
                // the ProcessExecutionListener guarantees each such event is only delivered once
                // either by this code, or by the ProcessHandler.

                boolean terminating = processHandler.isProcessTerminating();
                boolean terminated = processHandler.isProcessTerminated();
                if (terminating || terminated) {
                  listener.processWillTerminate(
                      new ProcessEvent(processHandler), false /*doesn't matter*/);

                  if (terminated) {
                    //noinspection ConstantConditions
                    int exitCode = processHandler.getExitCode();
                    listener.processTerminated(new ProcessEvent(processHandler, exitCode));
                  }
                }
              }
              environment.setContentToReuse(descriptor);
            }
          } catch (ProcessCanceledException e) {
            LOG.info(e);
          } catch (ExecutionException e) {
            ExecutionUtil.handleExecutionError(project, executor.getToolWindowId(), profile, e);
            LOG.info(e);
          } finally {
            if (!started) {
              project
                  .getMessageBus()
                  .syncPublisher(EXECUTION_TOPIC)
                  .processNotStarted(executor.getId(), environment);
            }
          }
        };

    if (ApplicationManager.getApplication().isUnitTestMode() && !myForceCompilationInTests) {
      startRunnable.run();
    } else {
      compileAndRun(
          () -> TransactionGuard.submitTransaction(project, startRunnable),
          environment,
          state,
          () -> {
            if (!project.isDisposed()) {
              project
                  .getMessageBus()
                  .syncPublisher(EXECUTION_TOPIC)
                  .processNotStarted(executor.getId(), environment);
            }
          });
    }
  }
  @Override
  public boolean executeTask(
      DataContext context,
      RunConfiguration configuration,
      ExecutionEnvironment env,
      ExternalSystemBeforeRunTask beforeRunTask) {

    final ExternalSystemTaskExecutionSettings executionSettings =
        beforeRunTask.getTaskExecutionSettings();

    final List<ExternalTaskPojo> tasks = ContainerUtilRt.newArrayList();
    for (String taskName : executionSettings.getTaskNames()) {
      tasks.add(new ExternalTaskPojo(taskName, executionSettings.getExternalProjectPath(), null));
    }
    if (tasks.isEmpty()) return true;

    final Pair<ProgramRunner, ExecutionEnvironment> pair =
        ExternalSystemUtil.createRunner(
            executionSettings, DefaultRunExecutor.EXECUTOR_ID, myProject, mySystemId);

    if (pair == null) return false;

    final ProgramRunner runner = pair.first;
    final ExecutionEnvironment environment = pair.second;
    environment.setExecutionId(env.getExecutionId());

    final Semaphore targetDone = new Semaphore();
    final Ref<Boolean> result = new Ref<Boolean>(false);
    final Disposable disposable = Disposer.newDisposable();

    final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
    final String executorId = executor.getId();

    myProject
        .getMessageBus()
        .connect(disposable)
        .subscribe(
            ExecutionManager.EXECUTION_TOPIC,
            new ExecutionAdapter() {
              public void processStartScheduled(
                  final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  targetDone.down();
                }
              }

              public void processNotStarted(
                  final String executorIdLocal,
                  @NotNull final ExecutionEnvironment environmentLocal) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  targetDone.up();
                }
              }

              public void processStarted(
                  final String executorIdLocal,
                  @NotNull final ExecutionEnvironment environmentLocal,
                  @NotNull final ProcessHandler handler) {
                if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                  handler.addProcessListener(
                      new ProcessAdapter() {
                        public void processTerminated(ProcessEvent event) {
                          result.set(event.getExitCode() == 0);
                          targetDone.up();
                          environmentLocal.getContentToReuse();
                        }
                      });
                }
              }
            });

    try {
      ApplicationManager.getApplication()
          .invokeAndWait(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    runner.execute(environment);
                  } catch (ExecutionException e) {
                    targetDone.up();
                    LOG.error(e);
                  }
                }
              },
              ModalityState.NON_MODAL);
    } catch (Exception e) {
      LOG.error(e);
      Disposer.dispose(disposable);
      return false;
    }

    targetDone.waitFor();
    Disposer.dispose(disposable);

    return result.get();
  }
Пример #4
0
  @Override
  public boolean executeTask(
      final DataContext dataContext,
      RunConfiguration configuration,
      final ExecutionEnvironment env,
      RunConfigurableBeforeRunTask task) {
    RunnerAndConfigurationSettings settings = task.getSettings();
    if (settings == null) {
      return false;
    }
    final Executor executor = DefaultRunExecutor.getRunExecutorInstance();
    final String executorId = executor.getId();
    ExecutionEnvironmentBuilder builder =
        ExecutionEnvironmentBuilder.createOrNull(executor, settings);
    if (builder == null) {
      return false;
    }
    final ExecutionEnvironment environment = builder.build();
    environment.setExecutionId(env.getExecutionId());
    if (!ExecutionTargetManager.canRun(settings, env.getExecutionTarget())) {
      return false;
    }

    if (!environment.getRunner().canRun(executorId, environment.getRunProfile())) {
      return false;
    } else {
      final Semaphore targetDone = new Semaphore();
      final Ref<Boolean> result = new Ref<Boolean>(false);
      final Disposable disposable = Disposer.newDisposable();

      myProject
          .getMessageBus()
          .connect(disposable)
          .subscribe(
              ExecutionManager.EXECUTION_TOPIC,
              new ExecutionAdapter() {
                @Override
                public void processStartScheduled(
                    final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    targetDone.down();
                  }
                }

                @Override
                public void processNotStarted(
                    final String executorIdLocal,
                    @NotNull final ExecutionEnvironment environmentLocal) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    targetDone.up();
                  }
                }

                @Override
                public void processStarted(
                    final String executorIdLocal,
                    @NotNull final ExecutionEnvironment environmentLocal,
                    @NotNull final ProcessHandler handler) {
                  if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
                    handler.addProcessListener(
                        new ProcessAdapter() {
                          @Override
                          public void processTerminated(ProcessEvent event) {
                            result.set(event.getExitCode() == 0);
                            targetDone.up();
                          }
                        });
                  }
                }
              });

      try {
        ApplicationManager.getApplication()
            .invokeAndWait(
                new Runnable() {
                  @Override
                  public void run() {
                    try {
                      environment.getRunner().execute(environment);
                    } catch (ExecutionException e) {
                      targetDone.up();
                      LOG.error(e);
                    }
                  }
                },
                ModalityState.NON_MODAL);
      } catch (Exception e) {
        LOG.error(e);
        Disposer.dispose(disposable);
        return false;
      }

      targetDone.waitFor();
      Disposer.dispose(disposable);

      return result.get();
    }
  }