com.github.rcaller.scriptengine.RCallerScriptEngine Maven / Gradle / Ivy
/*
*
RCaller, A solution for calling R from Java
Copyright (C) 2010-2016 Mehmet Hakan Satman
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program 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 Lesser General Public License
along with this program. If not, see .
*
*
* Mehmet Hakan Satman - [email protected]
* http://www.mhsatman.com
* Google code project: https://github.com/jbytecode/rcaller
* Please visit the blog page with rcaller label:
* http://stdioe.blogspot.com.tr/search/label/rcaller
*/
package com.github.rcaller.scriptengine;
import com.github.rcaller.EventHandler;
import com.github.rcaller.rstuff.RCaller;
import com.github.rcaller.rstuff.RCode;
import com.github.rcaller.rstuff.ROutputParser;
import com.github.rcaller.util.RCodeUtils;
import javax.script.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
public class RCallerScriptEngine implements ScriptEngine, EventHandler, Invocable {
final private RCaller rcaller;
private final RCode rcode;
private ROutputParser parser;
private Bindings bindings;
private ScriptContext context;
public RCallerScriptEngine() {
rcaller = RCaller.create();
rcode = RCode.create();
rcode.addRCode("result <- list(a=0)");
rcaller.setRCode(rcode);
rcaller.runAndReturnResultOnline("result");
context = new javax.script.SimpleScriptContext();
}
@Override
public Object eval(String code, ScriptContext sc) throws ScriptException {
return (this.eval(code));
}
@Override
public Object eval(Reader reader, ScriptContext sc) throws ScriptException {
return (this.eval(reader));
}
@Override
public Object eval(String code) throws ScriptException {
rcode.clearOnline();
rcode.addRCode(code);
rcode.addRCode("result <- list(a=0)");
rcaller.setRCode(rcode);
rcaller.runAndReturnResultOnline("result");
return (null);
}
@Override
public Object eval(Reader reader) throws ScriptException {
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
StringBuilder stringBuilder = new StringBuilder();
try {
while (true) {
line = bufferedReader.readLine();
if (line == null) {
break;
}
stringBuilder.append(line);
}
} catch (IOException ioe) {
throw new ScriptException("Error while reading from reader: " + ioe.toString());
}
return (this.eval(stringBuilder.toString()));
}
@Override
public Object eval(String code, Bindings bndngs) throws ScriptException {
return (this.eval(code));
}
@Override
public Object eval(Reader reader, Bindings bindings) throws ScriptException {
return (this.eval(reader));
}
@Override
public void put(String name, Object o) {
rcode.clearOnline();
StringBuffer code = new StringBuffer();
RCodeUtils.addRespectToType(code, name, o, false);
rcode.addRCode("result <- list(a=0)");
rcode.setCode(code);
rcaller.setRCode(rcode);
rcaller.runAndReturnResultOnline("result");
}
@Override
public Object get(String var) {
int[] dimension;
rcode.clearOnline();
rcode.addRCode("result <- ls()");
rcaller.runAndReturnResultOnline(var);
parser = rcaller.getParser();
parser.parse();
try {
//System.out.println(parser.getXMLFileAsString());
dimension = parser.getDimensions(var);
} catch (Exception e) {
return (parser.getAsStringArray(var));
}
String vartype = parser.getType(var);
if (dimension[0] > 1 && dimension[1] > 1) {
return (parser.getAsDoubleMatrix(var));
} else if (vartype.equals("numeric")) {
return (parser.getAsDoubleArray(var));
} else if (vartype.equals("character")) {
return (parser.getAsStringArray(var));
} else {
return (parser.getAsStringArray(var)); // :o
}
}
@Override
public Bindings getBindings(int i) {
return (this.bindings);
}
@Override
public void setBindings(Bindings bndngs, int i) {
this.bindings = bndngs;
}
@Override
public Bindings createBindings() {
return (new SimpleBindings());
}
@Override
public ScriptContext getContext() {
return (this.context);
}
@Override
public void setContext(ScriptContext sc) {
this.context = sc;
}
@Override
public ScriptEngineFactory getFactory() {
return (new RCallerScriptEngineFactory());
}
@Override
public void messageReceived(String senderName, String msg) {
System.out.println("RCaller Script Engine Received: (" + senderName + ") " + msg);
}
public void close() {
this.rcaller.StopRCallerOnline();
}
/*
Methods for invokable interface
*/
@Override
public Object invokeMethod(Object o, String fname, Object... arguments) throws ScriptException, NoSuchMethodException {
return (invokeFunction(fname, arguments));
}
@Override
public Object invokeFunction(String fname, Object... arguments) throws ScriptException, NoSuchMethodException {
int[] dimension = null;
String var = "fresult";
rcode.clearOnline();
rcode.addRCode(var + " <- " + fname + "(");
for (int i = 0; i < arguments.length; i++) {
NamedArgument named = (NamedArgument) arguments[i];
RCodeUtils.addRespectToType(rcode.getCode(), named.getName(), named.getObj(), true);
if (i != (arguments.length - 1)) {
rcode.addRCode(",");
}
}
rcode.addRCode(")");
rcaller.setRCode(rcode);
//Please do not delete, I like to see verbose output in development stage.
//System.out.println(rcode.getCode().toString());
rcaller.runAndReturnResultOnline(var);
parser = rcaller.getParser();
ArrayList namedResults = new ArrayList<>();
ArrayList names = rcaller.getParser().getNames();
for (String name : names) {
var = name;
try {
dimension = parser.getDimensions(var);
} catch (Exception e) {
namedResults.add(NamedArgument.Named(var, parser.getAsStringArray(var)));
}
String vartype = parser.getType(var);
assert dimension != null;
if (dimension[0] > 1 && dimension[1] > 1) {
namedResults.add(NamedArgument.Named(var, parser.getAsDoubleMatrix(var)));
} else if (vartype.equals("numeric")) {
namedResults.add(NamedArgument.Named(var, parser.getAsDoubleArray(var)));
} else if (vartype.equals("character")) {
namedResults.add(NamedArgument.Named(var, parser.getAsStringArray(var)));
} else {
namedResults.add(NamedArgument.Named(var, parser.getAsStringArray(var)));
}
}
return (namedResults);
}
@Override
public T getInterface(Class type) {
return (null);
}
@Override
public T getInterface(Object o, Class type) {
return (null);
}
/*
End of Methods for invokable interface
*/
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy