Package edu.ucsd.hep.rootrunnerutil

Source Code of edu.ucsd.hep.rootrunnerutil.ROOTRunnerImpl

/*
* Copyright 2012 University of California, San Diego.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.ucsd.hep.rootrunnerutil;

import edu.ucsd.hep.rootrunnerutil.misc.InputStreamDumper;
import edu.ucsd.hep.rootrunnerutil.misc.InputStreamFanOut;
import edu.ucsd.hep.rootrunnerutil.shell.ShellPipeCommandRunner;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.language.DefaultTemplateLexer;

/**
* Newer implementation of a ROOTRunner
* @author holzner
*/
public class ROOTRunnerImpl extends ROOTRunner
{
  //----------------------------------------------------------------------
  private InputStreamSplitter markerFinder;
 
  /** if specified, this command will be used transfer
   *  a remote file locally */
  private String transferRemoteFileToLocalCmd;
 
  /** if non-null, this command is used to create a temporary file
   *  (e.g. remotely) */
  private String createTempFileCmd;
 
  //----------------------------------------------------------------------

  /** @param shell_initialization_commands is prepended to the root command
   *  (without any spaces or separators)
   *
   * @param commandRunnerListenerFactories is a list of factories for creating
   *        objects that will be notified whenever some lines are read or written
   *        to the ROOT process. Can be null (this is equivalent to
   *        an empty list)
   *
   * @param shell_initialization_commands commands executed on the shell before starting ROOT
   */
  public ROOTRunnerImpl(List<PipeCommandRunnerListener> commandRunnerListeners,
    String root_cmd_args,
    String shell_initialization_commands,
    PipeCommandRunnerWorkerFactory runnerFactory,
    String rootCmd)
  {
    if (rootCmd != null)
      this.setROOTCommand(rootCmd);
   
    if (commandRunnerListeners == null)
      this.commandRunnerListeners = new ArrayList<PipeCommandRunnerListener>();
    else
      this.commandRunnerListeners = new ArrayList<PipeCommandRunnerListener>(commandRunnerListeners);
   
    // remove all null listeners (which can come in from the other constructor
    // being called with a null pointer)
    for (Iterator<PipeCommandRunnerListener> it = this.commandRunnerListeners.iterator();
         it.hasNext();)
    {
      if (it.next() == null)
        it.remove();
    }

   
    this.runnerFactory = runnerFactory;

    if (root_cmd_args != null)
      this.root_cmd_args = root_cmd_args;
    else
      this.root_cmd_args = "-b";
    this.initialization_commands = shell_initialization_commands;

    // start the pipe to ROOT right now
    getROOTPipe();

    // TODO: we should make sure that the ROOT process is killed
    //       on program exit: see http://www.exampledepot.com/egs/java.lang/ExitHook.html

  }

  //----------------------------------------------------------------------
  /** convenience constructor for just one PipeCommandRunnerListenerFactory */
  public ROOTRunnerImpl(PipeCommandRunnerListener commandRunnerListener,
    String root_cmd_args,
    String shell_initialization_commands,
    PipeCommandRunnerWorkerFactory runnerFactory,
    String rootCmd)
  {
    this(AHUtils.makeList(commandRunnerListener),
      root_cmd_args,
      shell_initialization_commands,
      runnerFactory,
      rootCmd);
  }
 
  //----------------------------------------------------------------------


  /** @return the characters read before the command completed. Does NOT
      reset the recording buffer of markerFinder */
  @Override
  public String waitForCompletion()
  {
    Marker marker = sendMarker();
    return waitForString(marker.getString());
  }
  //----------------------------------------------------------------------

  public String waitForString(String str)
  {
    // TODO: add support for detecting when ROOT crashed
    // and produced a stack trace
    try
    {
      markerFinder.enableRecording(true);
     
      this.markerFinder.readToString(str)
      return this.markerFinder.getRecordings();
    } catch (IOException ex)
    {
      Logger.getLogger(ROOTRunnerOld.class.getName()).log(Level.SEVERE, null, ex);
      return null;
    }
  }
 
  //----------------------------------------------------------------------

    /** default implementation for starting ROOT */
  protected void startROOT() throws Exception
  {
    String cmd = rootCmd + " " + (root_cmd_args != null ? root_cmd_args : "");
    if (initialization_commands != null)
      cmd = initialization_commands + "\n" + cmd;
    // File cmd_script = makeROOTstartFile(cmd);
   
    if (this.runnerFactory != null)
      root_pipe = new PipeCommandRunner(runnerFactory.makeWorker(
        cmd
        // cmd_script.getAbsolutePath()
          )
        );
    else
      root_pipe = new PipeCommandRunner(new ShellPipeCommandRunner(cmd));
   
    this.root_stdout_for_checkpointing = root_pipe.getCommandStdoutStream();//.getROOTStdoutStream();
   
    // for debugging
    if (false)
    {
      List<InputStream> isClones = InputStreamFanOut.makeClones(root_stdout_for_checkpointing, 2);
      root_stdout_for_checkpointing = isClones.get(0);

      InputStreamDumper debugDumper = new InputStreamDumper(System.err, isClones.get(1), "GOT FROM ROOT:");
      debugDumper.start();
    }
   
    // for each listener factory, create a listener
    for (PipeCommandRunnerListener listener : this.commandRunnerListeners)
    {
      root_pipe.addListener(listener);
    }
 
    //----------
    // DIFFERENCE TO THE OLD IMPLEMENTATION
    //----------
    this.markerFinder = new InputStreamSplitter(this.root_stdout_for_checkpointing);
   
    //----------

    // wait for ROOT prompt
    this.waitForString("W E L C O M E  to  R O O T");
  }

  //----------------------------------------------------------------------

  @Override
  public String getCommandOutput(String cmd) throws IOException
  {
    clearPrompt();
   
    // synchronize first
    System.out.println("first synchronization");
    this.waitForCompletion();

    this.markerFinder.clearRecordings();
   
    this.writeLine(cmd);

    System.out.println("second synchronization");
    return this.waitForCompletion();
  }
  //----------------------------------------------------------------------

  /** each command in cmds should end with a semicolon, no semicolon
   *  is appended here */
  @Override
  public List<String> getMultipleCommandsOutputBatch(List<String> cmds) throws IOException
  {
    List<String> retval = new ArrayList<String>();

    if (cmds.isEmpty())
      // no commands, no output (we catch this here because later
      // on we assume that the output file contains at least one marker)
      return retval;
   
   
    List<String> markers = new ArrayList<String>();

    // note that we have to put the code inside braces for ROOT to run
    // it properly but variables defined at the interactive prompt
    // are visible in the macro

    // TODO: will this be deleted at program exit ?
    File macroFile = File.createTempFile("rootRunner", ".C");
    //-----
    // create a macro file containing all the commands
    // add markers (which are drawn from random numbers rather
    // than from time stamps because what we do here is quite
    // close in time)
    //-----
    PrintStream out = new PrintStream(new FileOutputStream(macroFile));
   
    out.println("{");

    for (String cmd : cmds)
    {
      out.println(cmd);
     
      // write the marker generating command
      Marker marker = new Marker();
      out.println(marker.getCommand());
      markers.add(marker.getString());
    }
   
    out.println("}");
   
    // the file to collect the output
    File outputFile = File.createTempFile("rootRunner", null);
   
    //-----
    // then run it (with instantaneous compilation using ACLIC)
    //-----
    // System.out.println("MACRO=" + macroFile.getAbsolutePath());
    // System.out.println("output=" + outputFile.getAbsolutePath());
   
   
   
   
    // redirecting everytghing to a single output file
    // seems NOT to work; when we send a marker afterwards
    // this marker seems never to be printed
   
    markerFinder.clearRecordings();
    markerFinder.enableRecording(true);
    this.writeLine(".x " + macroFile.getAbsolutePath()
            /* + "+ >" + outputFile.getAbsolutePath() */);
   
    // running waitForCompletion(..) immediately seems not to work
    //
    // trying a workaround: wait until the output file has non-zero
    // size (we write at least one marker to the file, so
    // the output file must have non-zero size)
  
    // File.length() returns 0 if the file does not exist
   
//    while (outputFile.length() == 0)
//    {
//      AHUtils.sleepSeconds(0.1);
//    }
//   

    // wait for each of the markers
    int i = 1;
    for (String marker : markers)
    {
      // System.out.println("ZZZ " + marker + " " + i + " of " + markers.size() + " " + cmds.get(i-1));
      this.markerFinder.readToString(marker);
      retval.add(this.markerFinder.getRecordings());
      this.markerFinder.clearRecordings();
     
      ++i;
    }
   
   
//    // this.waitForString("root [");
//    // only now send the marker command
//    this.waitForCompletion();
//   
//    //-----
//    // parse the results (i.e. split by markers)
//    //-----
//    InputStreamSplitter markerReader = new InputStreamSplitter(new FileInputStream(outputFile));
//   
//
//    for (String marker : markers)
//    {
//      markerReader.enableRecording(true);
//      markerReader.readToString(marker);
//      retval.add(markerReader.getRecordings());
//     
//      markerReader.clearRecordings();
//    }
//
    return retval;

  }

  //----------------------------------------------------------------------

  public void setTransferRemoteFileToLocalCmd(String transferRemoteFileToLocalCmd)
  {
    this.transferRemoteFileToLocalCmd = transferRemoteFileToLocalCmd;
  }

  public void setCreateTempFileCmd(String createTempFileCmd)
  {
    this.createTempFileCmd = createTempFileCmd;
  }

  //----------------------------------------------------------------------
 
  @Override
  public byte[] readFile(String fname) throws IOException
  {
    // check if we have a special command to transfer a remote file locally
    if (transferRemoteFileToLocalCmd != null)
    {
      // first transfer the file locally into a temporary file, then
      // read it
      File localTempFile = File.createTempFile("rootRunner", null);

     
      System.err.println("transferRemoteFileToLocalCmd=" + transferRemoteFileToLocalCmd);
      StringTemplate template = new StringTemplate(transferRemoteFileToLocalCmd, DefaultTemplateLexer.class);     
      template.setAttribute("remotefile", fname);
      template.setAttribute("localfile", localTempFile.getAbsolutePath());
     
      String cmd = template.toString();
     
      System.err.println("executing command to copy a file locally: " + cmd);
     
      // execute the command
      Process proc = Runtime.getRuntime().exec(cmd);
      AHUtils.waitForCommandCompletion(proc);
     
      byte[] retval = AHUtils.readFileToByteArray(localTempFile.getAbsolutePath());
     
      // delete the local temporary file
      localTempFile.delete();
     
      return retval;
     
    }
    else
      return AHUtils.readFileToByteArray(fname);
  }

  //----------------------------------------------------------------------

  @Override
  public String createTempFile(String prefix, String suffix) throws IOException
  {
    if (this.createTempFileCmd != null)
    {
      // run the command and read the first line of its output
     
      System.err.println("executing a command to create a (remote) temporary file: " + this.createTempFileCmd);
     
      String output = AHUtils.readCommandOutput(this.createTempFileCmd);
     
      System.out.println("GOT OUTPUT: '" + output + "'");
      List<String> lines = AHUtils.splitToLines(output);
     
      return lines.get(0);
     
    }
    else
    {
      File tempFile = File.createTempFile(prefix, suffix);
      return tempFile.getAbsolutePath();
    }
  }

  //----------------------------------------------------------------------

}
TOP

Related Classes of edu.ucsd.hep.rootrunnerutil.ROOTRunnerImpl

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.