
prerna.reactor.frame.r.util.RJavaUserRserveTranslator Maven / Gradle / Ivy
The newest version!
package prerna.reactor.frame.r.util;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Vector;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.RFactor;
import org.rosuda.REngine.RList;
import org.rosuda.REngine.Rserve.RConnection;
import prerna.auth.AccessToken;
import prerna.auth.AuthProvider;
import prerna.auth.User;
import prerna.auth.utils.WorkspaceAssetUtils;
import prerna.engine.impl.r.IRUserConnection;
import prerna.engine.impl.r.RUserConnectionDedicated;
import prerna.engine.impl.r.RserveUtil;
import prerna.util.Constants;
import prerna.util.Utility;
public class RJavaUserRserveTranslator extends AbstractRJavaTranslator {
private static final Logger logger = LogManager.getLogger(RJavaUserRserveTranslator.class);
private IRUserConnection rcon;
private boolean envConfig = false;
////////////////////////////////////////
// Starting R
////////////////////////////////////////
@Override
public void startR() {
// Try to start R
try {
// First define the rcon
if (userRconIsDefined()) {
rcon = this.insight.getUser().getRcon();
} else {
if (userIsDefined()) {
this.insight.getUser().setRcon(IRUserConnection.getRUserConnection(getRDataFile()));
rcon = this.insight.getUser().getRcon();
} else {
rcon = IRUserConnection.getRUserConnection();
}
// Then initialize
rcon.initializeConnection();
rcon.loadDefaultPackages();
// this needs to be at the every instance level. so moved this to factory
//initREnv(); // TODO>>>timb: R - why do we need these? They are not called in recover methods of the RUserConnection framework (later)
}
//TODO
if ( !envConfig){
// Doesnt setMemoryLimit need to be moved as well? Every insight is a new env so we need to reset that every time.
initREnv();
setMemoryLimit();
removeRFunctions();
envConfig = true;
}
} catch (Exception e) {
// If r fails to start, don't preserve the improperly loaded object
if (rcon != null) {
try {
rcon.stopR();
} catch (Exception ignore) {
// Nothing to do here
} finally {
this.insight.getUser().setRcon(null);
}
}
throw new IllegalArgumentException("Failed to start R: " + e.getMessage(), e);
}
// need to set the rprocess in the user
if(this.insight != null && this.insight.getUser() != null && rcon instanceof RUserConnectionDedicated)
{
this.insight.getUser().setrProcess(rcon.getProcess());
this.insight.getUser().setrPort(((RUserConnectionDedicated)rcon).getPort());
}
}
private boolean userRconIsDefined() {
return userIsDefined() && this.insight.getUser().getRcon() != null;
}
private boolean userIsDefined() {
return this.insight != null && this.insight.getUser() != null;
}
private String getUserInfo() {
String userInfo = null;
User user = this.insight.getUser();
if(user.isAnonymous()) {
userInfo = "unk" + "___" + user.getAnonymousId();
} else {
AuthProvider primaryProvider = user.getPrimaryLogin();
AccessToken token = user.getAccessToken(primaryProvider);
if(token.getName() == null) {
userInfo = primaryProvider.name() + "___noname_" + UUID.randomUUID();
} else {
userInfo = primaryProvider.name() + "___" + token.getName().replace(" ", "_");
}
}
return userInfo;
}
private String getRDataFile() {
if (userIsDefined()) {
// do we have a user workspace and is the person logged in?
if ( Boolean.parseBoolean(Utility.getDIHelperProperty(Constants.USER_WORKSPACE)) && !this.insight.getUser().isAnonymous() ) {
String assetDirectory = WorkspaceAssetUtils.getUserAssetRootDirectory(this.insight.getUser(), this.insight.getUser().getPrimaryLogin());
if (assetDirectory != null && new File(assetDirectory).isDirectory()) {
String rDataDirectory = assetDirectory + "/" + "RData";
new File(rDataDirectory).mkdir();
return RserveUtil.getRDataFile(rDataDirectory, getUserInfo());
}
}
return RserveUtil.getRDataFile(getUserInfo());
} else {
return RserveUtil.getRDataFile("anonymous");
}
}
@Override
public void initREnv() {
try {
rcon.eval("if(!exists(\"" + this.env + "\")) {" + this.env + "<- new.env();}");
} catch (Exception e) {
throw new IllegalArgumentException("Failed to initialize R environment.", e);
}
}
////////////////////////////////////////
// R evaluations
////////////////////////////////////////
@Override
public Object executeR(String rScript) {
// escape quotes
//rScript = rScript.replaceAll("\"", "\\\"");
//rScript = rScript.replaceAll("'", "\\'");
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript);
}
@Override
public void executeEmptyR(String rScript) {
// escape quotes
//rScript = rScript.replaceAll("\"", "\\\"");
//rScript = rScript.replaceAll("'", "\\'");
rScript = encapsulateForEnv(rScript);
rcon.voidEval(rScript);
}
@Override
public Object executeRDirect(String rScript) {
return rcon.eval(rScript);
}
@Override
public void executeEmptyRDirect(String rScript) {
rcon.voidEval(rScript);
}
////////////////////////////////////////
// Cancellation
////////////////////////////////////////
@Override
public boolean cancelExecution() {
return false;
// TODO >>>timb: R - need to complete cancellation here (later)
}
////////////////////////////////////////
// Raw R connection
////////////////////////////////////////
// TODO >>>timb: R - should get rid of this (later)
@Deprecated
public RConnection getConnection() {
return rcon.getRConnection();
}
////////////////////////////////////////
// Data types
////////////////////////////////////////
@Override
public String getString(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asString();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a string.");
}
}
@Override
public String[] getStringArray(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asStrings();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a string array.");
}
}
/**
* This method is used to get the column types of a frame
*
* @param frameName
*/
public String[] getColumnTypes(String frameName) {
String rScript = "sapply(" + frameName + ", class);";
rScript = encapsulateForEnv(rScript);
REXP val = rcon.eval(rScript);
try {
return val.asStrings();
} catch (REXPMismatchException e) {
// ignore
}
try {
RList list = val.asList();
int size = list.size();
String[] arr = new String[size];
for(int i = 0; i < size; i++) {
Object v = list.get(i);
if(v instanceof REXP) {
try {
REXP vRexp = (REXP) v;
arr[i] = vRexp.asString();
} catch (REXPMismatchException e) {
// could be an array
// actually, seems like RServe
// will give you the first element
// of an array if you use asString
// even if asStrings() works
REXP vRexp = (REXP) v;
arr[i] = vRexp.asStrings()[0];
}
} else {
arr[i] = v.toString();
}
}
return arr;
} catch (REXPMismatchException e) {
logger.error(Constants.STACKTRACE, e);
}
return null;
}
@Override
public int getInt(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asInteger();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to an integer.");
}
}
@Override
public int[] getIntArray(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asIntegers();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to an integer array.");
}
}
@Override
public double getDouble(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asDouble();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a double.");
}
}
@Override
public double[] getDoubleArray(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asDoubles();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a double array.");
}
}
@Override
public double[][] getDoubleMatrix(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asDoubleMatrix();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a double matrix.");
}
}
@Override
public boolean getBoolean(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asInteger() == 1;
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a inter.");
}
}
@Override
public Object getFactor(String rScript) {
try {
rScript = encapsulateForEnv(rScript);
return rcon.eval(rScript).asFactor();
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to a factor.");
}
}
@Override
public void setConnection(RConnection connection) {
// This is not necessary as connection is allocated per user
}
@Override
public void setPort(String port) {
// This is not necessary as port is allocated per user
}
@Override
/**
* Stops all r processes.
*/
public void endR() {
try {
RserveUtil.endR();
} catch (Exception e) {
logger.warn("Unable to end R.", e);
}
}
@Override
public void stopRProcess() {
try {
rcon.detach();
} catch (Exception e) {
logger.warn("Unable to stop R process.", e);
}
}
@Override
public Map getHistogramBreaksAndCounts(String rScript) {
rScript = encapsulateForEnv(rScript);
try {
double[] breaks;
@SuppressWarnings("unchecked")
Map histJ = (Map) (rcon.eval(rScript).asNativeJavaObject());
if (histJ.get("breaks") instanceof int[]) {
int[] breaksInt = (int[]) histJ.get("breaks");
breaks = Arrays.stream(breaksInt).asDoubleStream().toArray();
} else {
breaks = (double[]) histJ.get("breaks");
}
int[] counts = (int[]) histJ.get("counts");
Map retMap = new HashMap<>();
retMap.put("breaks", breaks);
retMap.put("counts", counts);
return retMap;
} catch (REXPMismatchException e) {
throw new IllegalArgumentException("R did not evaluate to the proper data type.", e);
}
}
@Override
public Map flushFrameAsTable(String framename, String[] colNames) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy