package fr.ens.biologie.genomique.eoulsan.util.r; import static fr.ens.biologie.genomique.eoulsan.EoulsanLogger.getLogger; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Arrays; import java.util.List; import org.rosuda.REngine.REXPMismatchException; import org.rosuda.REngine.REngineException; import fr.ens.biologie.genomique.eoulsan.EoulsanRuntime; import fr.ens.biologie.genomique.eoulsan.data.DataFile; /** * This class define a RServe RExecutor. * @author Laurent Jourdren * @since 2.0 */ public class RserveRExecutor extends AbstractRExecutor { public static final String REXECUTOR_NAME = "rserve"; private final String serverName; protected RSConnection rConnection; @Override public String getName() { return REXECUTOR_NAME; } @Override public void getOutputFiles() throws IOException { checkConnection(); try { // Get all the filenames final List<String> filenames = this.rConnection.listFiles(); for (String filename : filenames) { // Retrieve the file this.rConnection.getFile(filename, new File(getOutputDirectory(), filename)); // Delete the file removeFile(filename); } } catch (REngineException | REXPMismatchException e) { throw new IOException(e); } } // // Protected methods // @Override public void openConnection() throws IOException { // Check if temporary and output directories exists super.openConnection(); this.rConnection = new RSConnection(serverName); } @Override public void closeConnection() throws IOException { this.rConnection.disConnect(); this.rConnection = null; } @Override protected void removeFile(final String filename) throws IOException { checkConnection(); // Check if Rserve files can be removed if (EoulsanRuntime.getSettings().isKeepRServeFiles()) { return; } // Remove file from Rserve server try { this.rConnection.removeFile(filename); } catch (REngineException e) { throw new IOException(e); } } protected void putFile(final DataFile inputFile, final String inputFilename) throws IOException { checkConnection(); getLogger() .info("Put file on RServe: " + inputFile + " to " + inputFilename); try { this.rConnection.putFile(inputFile.open(), inputFilename); } catch (REngineException e) { throw new IOException(e); } } @Override public void writerFile(final String content, final String outputFilename) throws IOException { checkConnection(); if (content == null) { throw new NullPointerException("content argument cannot be null"); } if (outputFilename == null) { throw new NullPointerException("outputFilename argument cannot be null"); } try (Writer writer = new OutputStreamWriter( this.rConnection.getFileOutputStream(outputFilename))) { writer.write(content); } catch (REngineException e) { throw new IOException(e); } } @Override protected void executeRScript(final File rScriptFile, final boolean sweave, final String sweaveOuput, final File workflowOutputDir, final String... scriptArguments) throws IOException { checkConnection(); final String rScriptOnRservePath = rScriptFile.getName(); // Put the R script on the Rserve server putFile(new DataFile(rScriptFile), rScriptOnRservePath); try { // Set the command line arguments if (scriptArguments != null) { this.rConnection.setCommandArgs(Arrays.asList(scriptArguments)); } if (sweave) { // Execute Sweave script getLogger().info("Execute RNW script: " + rScriptFile); this.rConnection.executeRnwCode(rScriptOnRservePath, sweaveOuput); } else { // Execute a R script getLogger().info("Execute R script: " + rScriptFile); this.rConnection.executeRCode(rScriptOnRservePath); } } catch (REngineException e) { throw new IOException(e); } // Remove the R script on the server removeFile(rScriptOnRservePath); } // // Other methods // private void checkConnection() { if (this.rConnection == null) { throw new IllegalStateException("Connection has not been openned"); } } // // Constructor // /** * Public constructor. * @param outputDirectory the output directory * @param temporaryDirectory the temporary directory * @param serverName Rserve server name * @throws IOException */ public RserveRExecutor(final File outputDirectory, final File temporaryDirectory, final String serverName) throws IOException { super(outputDirectory, temporaryDirectory); if (serverName == null) { throw new NullPointerException("serverName cannot be null"); } this.serverName = serverName.trim(); } }