/* This file is part of jTotus. jTotus is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jTotus is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with jTotus. If not, see <http://www.gnu.org/licenses/>. */ package org.jlucrum.realtime.ranalyzer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rosuda.REngine.REXP; import org.rosuda.REngine.Rserve.RConnection; import org.rosuda.REngine.Rserve.RserveException; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; /** * @author Evgeni Kappinen */ public class Rexecutor { private static boolean serverStarted = false; private final static Log log = LogFactory.getLog(Rexecutor.class); private final static String os = System.getProperty("os.name").toLowerCase(); private RConnection connection = null; /** * Starts RServe daemon * * @return false on failure */ private synchronized static boolean startRServe() { BufferedReader stderr = null; if (serverStarted) { return serverStarted; } try { String rserverStartUp = null; log.info("Starting RServe"); if (os.startsWith("windows")) { // lower cased rserverStartUp = System.getenv("R_HOME") + File.separator + "library" + File.separator + "Rserve" + File.separator + "Rserve.exe"; } else { rserverStartUp = "/usr/bin/R CMD Rserve --no-save"; } ProcessBuilder builder = new ProcessBuilder(rserverStartUp.split(" ")); Process process = builder.start(); stderr = new BufferedReader(new InputStreamReader(process.getErrorStream())); int ret = process.waitFor(); if (ret == 0) { log.info("RServe is started"); serverStarted = true; } else { String line; while ((line = stderr.readLine()) != null) { System.err.println(line); System.err.flush(); } } } catch (InterruptedException ex) { Logger.getLogger(Rexecutor.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(Rexecutor.class.getName()).log(Level.SEVERE, null, ex); } finally { if (stderr != null) { try { stderr.close(); } catch (IOException ex) { Logger.getLogger(Rexecutor.class.getName()).log(Level.SEVERE, null, ex); } } } return serverStarted; } /** * @return the connection */ public RConnection getConnection() throws RserveException { //FIMXE: login & password from config file! if (connection == null || !connection.isConnected()) { startRServe(); connection = new RConnection(); } return connection; } /** * @param connection the connection to set */ public void setConnection(RConnection connection) { this.connection = connection; } public REXP eval(String pattern, Object... arguments) { try { String cmd = String.format(pattern, arguments); return getConnection().eval(cmd); } catch (RserveException ex) { log.error("Failure in getting connection to RServer"); } finally { //TODO: close/shutdown connection ? } return new REXP(); } }