Package com.google.jstestdriver.idea.server

Source Code of com.google.jstestdriver.idea.server.JstdServer$MyDisposable

package com.google.jstestdriver.idea.server;

import com.google.common.base.Charsets;
import com.google.gson.stream.JsonWriter;
import com.google.jstestdriver.JsTestDriverServer;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.*;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class JstdServer {

  private static final Logger LOG = Logger.getInstance(JstdServer.class);
  private static final AtomicInteger NEXT_ID = new AtomicInteger(1);

  private final JstdServerSettings mySettings;
  private final OSProcessHandler myProcessHandler;
  private final String myName;
  private final MyDisposable myDisposable;
  private final JstdServerOutputProcessor myOutputProcessor;
  private final JstdServerLifeCycleManager myLifeCycleManager;

  public JstdServer(@NotNull JstdServerSettings settings) throws IOException {
    int id = NEXT_ID.getAndIncrement();
    mySettings = settings;
    myProcessHandler = start(settings, id);
    myName = formatName(id, myProcessHandler.getProcess());
    myOutputProcessor = new JstdServerOutputProcessor(myProcessHandler);
    myProcessHandler.startNotify();
    myLifeCycleManager = new JstdServerLifeCycleManager();
    myOutputProcessor.addListener(myLifeCycleManager);
    myDisposable = new MyDisposable();
    myProcessHandler.addProcessListener(new ProcessAdapter() {
      @Override
      public void processTerminated(ProcessEvent event) {
        LOG.info(myName + " terminated with exit code " + event.getExitCode());
        myLifeCycleManager.onTerminated(event.getExitCode());
        Disposer.dispose(myDisposable);
      }
    });
    Disposer.register(ApplicationManager.getApplication(), myDisposable);
  }

  public boolean isProcessRunning() {
    return !myProcessHandler.isProcessTerminated();
  }

  @NotNull
  public JstdServerSettings getSettings() {
    return mySettings;
  }

  @NotNull
  public String getServerUrl() {
    return "http://127.0.0.1:" + mySettings.getPort();
  }

  public boolean isReadyForCapturing() {
    return isProcessRunning() && myLifeCycleManager.isServerStarted() && !myLifeCycleManager.isServerStopped();
  }

  public boolean isReadyForRunningTests() {
    return isReadyForCapturing() && !getCapturedBrowsers().isEmpty();
  }

  @NotNull
  public Collection<JstdBrowserInfo> getCapturedBrowsers() {
    return myLifeCycleManager.getCapturedBrowsers();
  }

  public boolean isStopped() {
    return myLifeCycleManager.isServerStopped();
  }

  @NotNull
  private static OSProcessHandler start(@NotNull JstdServerSettings settings, int id) throws IOException {
    GeneralCommandLine commandLine = createCommandLine(settings);
    OSProcessHandler processHandler;
    try {
      processHandler = new KillableColoredProcessHandler(commandLine);
    }
    catch (ExecutionException e) {
      throw new IOException("Cannot start " + formatName(id, null) + ".\nCommand: " + commandLine.getCommandLineString(), e);
    }
    LOG.info(formatName(id, processHandler.getProcess()) + " started successfully: " + commandLine.getCommandLineString());
    ProcessTerminatedListener.attach(processHandler);
    processHandler.setShouldDestroyProcessRecursively(true);
    return processHandler;
  }

  private static String formatName(int id, @Nullable Process process) {
    String name = "JstdServer#" + id;
    if (process != null && SystemInfo.isUnix) {
      try {
        int pid = UnixProcessManager.getProcessPid(process);
        name += " (pid " + pid + ")";
      }
      catch (Exception ignored) {
      }
    }
    return name;
  }

  private static GeneralCommandLine createCommandLine(@NotNull JstdServerSettings settings) {
    GeneralCommandLine commandLine = new GeneralCommandLine();
    commandLine.setExePath(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
    Charset charset = Charsets.UTF_8;
    commandLine.setCharset(charset);
    commandLine.addParameter("-Dfile.encoding=" + charset.name());
    //commandLine.addParameter("-Xdebug");
    //commandLine.addParameter("-Xrunjdwp:transport=dt_socket,address=5000,server=y,suspend=y");

    File file = new File(PathUtil.getJarPathForClass(JsTestDriverServer.class));
    commandLine.setWorkDirectory(file.getParentFile());

    commandLine.addParameter("-cp");
    commandLine.addParameter(getClasspath());

    commandLine.addParameter("com.google.jstestdriver.idea.server.JstdServerMain");

    commandLine.addParameter("--port");
    commandLine.addParameter(String.valueOf(settings.getPort()));

    commandLine.addParameter("--runnerMode");
    commandLine.addParameter(settings.getRunnerMode().name());

    commandLine.addParameter("--browserTimeout");
    commandLine.addParameter(String.valueOf(settings.getBrowserTimeoutMillis()));

    return commandLine;
  }

  @NotNull
  private static String getClasspath() {
    Class[] classes = new Class[] {JsTestDriverServer.class, JstdServerMain.class, JsonWriter.class};
    List<String> result = ContainerUtil.newArrayList();
    for (Class clazz : classes) {
      String path = PathUtil.getJarPathForClass(clazz);
      File file = new File(path);
      result.add(file.getAbsolutePath());
    }
    return StringUtil.join(result, File.pathSeparator);
  }

  public void addOutputListener(@NotNull final JstdServerOutputListener listener) {
    UIUtil.invokeLaterIfNeeded(new Runnable() {
      @Override
      public void run() {
        myOutputProcessor.addListener(listener);
      }
    });
  }

  public void addLifeCycleListener(@NotNull JstdServerLifeCycleListener listener, @NotNull final Disposable disposable) {
    myLifeCycleManager.addListener(listener, disposable);
  }

  public void removeLifeCycleListener(@NotNull JstdServerLifeCycleListener listener) {
    myLifeCycleManager.removeListener(listener);
  }

  public void shutdownAsync() {
    if (!myProcessHandler.isProcessTerminated()) {
      LOG.info(myName + ": shutting down asynchronously...");
      ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
        @Override
        public void run() {
          if (!myProcessHandler.isProcessTerminated()) {
            ScriptRunnerUtil.terminateProcessHandler(myProcessHandler, 1000, myProcessHandler.getCommandLine());
          }
        }
      });
    }
  }

  @Override
  public String toString() {
    return myName;
  }

  private class MyDisposable implements Disposable {

    private volatile boolean myDisposed = false;

    @Override
    public void dispose() {
      if (myDisposed) {
        return;
      }
      LOG.info("Disposing " + myName);
      shutdownAsync();
      myOutputProcessor.dispose();
    }
  }

}
TOP

Related Classes of com.google.jstestdriver.idea.server.JstdServer$MyDisposable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.