blob: e4008f7e9b09f4f3cee76d06a6420933baf7cff8 [file] [log] [blame]
/*********************************************************************
* Copyright (c) 2008 The University of York.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.emc.simulink.engine;
import java.lang.reflect.Method;
import java.util.concurrent.Future;
import org.eclipse.epsilon.emc.simulink.exception.MatlabException;
import org.eclipse.epsilon.emc.simulink.util.MatlabEngineUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MatlabEngine {
/** ENGINE COMMANDS */
private static final String CONNECT_MATLAB_METHOD = "connectMatlab";
private static final String GET_VARIABLE_METHOD = "getVariable";
private static final String EVAL_METHOD = "eval";
private static final String EVAL_ASYNC_METHOD = "evalAsync";
private static final String RESULT = "result";
private static final String ASIGN = " = ";
private static final String PARAM_REGEX = "[?]";
/** ERRORS */
private static final String ERROR_INVALID_PARAMETER_NUMBER = "%d parameters were expected but %d were provided";
private static final Logger LOGGER = LoggerFactory.getLogger(MatlabEngine.class);
/** VARIABLES */
protected Object engine;
protected Method evalMethod;
protected Method getVariableMethod;
protected Method evalAsyncMethod;
public MatlabEngine(Class<?> matlabEngineClass) throws Exception {
try{
engine = matlabEngineClass.getMethod(CONNECT_MATLAB_METHOD).invoke(null);
} catch (Exception e) {
System.out.println("retrying connection");
engine = matlabEngineClass.getMethod(CONNECT_MATLAB_METHOD).invoke(null);
}
evalMethod = engine.getClass().getMethod(EVAL_METHOD, String.class);
getVariableMethod = engine.getClass().getMethod(GET_VARIABLE_METHOD, String.class);
evalAsyncMethod = engine.getClass().getMethod(EVAL_ASYNC_METHOD, String.class);
}
public Object evalWithSetupAndResult(String setup, String cmd, Object... parameters) throws MatlabException {
eval(setup + (setup.endsWith(";") ? "" : ";") + RESULT + ASIGN + cmd, parameters);
return getVariable(RESULT);
}
public Object evalWithResult(String cmd) throws MatlabException {
eval(RESULT + ASIGN + cmd);
return getVariable(RESULT);
}
public Object evalWithResult(String cmd, Object... parameters) throws MatlabException {
eval(RESULT + ASIGN + cmd, parameters);
return getVariable(RESULT);
}
public void eval(String cmd, Object... parameters) throws MatlabException {
cmd = " " + cmd + " ";
String[] parts = cmd.split(PARAM_REGEX);
if (parts.length != parameters.length + 1) {
String error = String.format(ERROR_INVALID_PARAMETER_NUMBER, parts.length - 1, parameters.length);
throw new RuntimeException(error);
}
cmd = parts[0];
for (int i = 0; i < parameters.length; i++) {
cmd += String.valueOf(parameters[i]).replace("'", "''").replace("\n", "\\n") + parts[i + 1];
}
cmd = cmd.substring(1, cmd.length() - 1);
eval(cmd);
}
public void eval(String cmd) throws MatlabException {
try {
LOGGER.debug(cmd);
evalMethod.invoke(engine, cmd);
} catch (Exception e) {
LOGGER.debug(e.getMessage());
throw new MatlabException(e);
}
}
public Object getVariable(String variable) throws MatlabException {
try {
return MatlabEngineUtil.parseMatlabEngineVariable(getVariableMethod.invoke(engine, variable));
} catch (Exception e) {
throw new MatlabException(e);
}
}
@SuppressWarnings("unchecked")
public Future<Void> evalAsync(String cmd) throws MatlabException {
try {
Method evalSyncMethod = engine.getClass().getMethod(EVAL_ASYNC_METHOD, String.class);
return (Future<Void>) evalSyncMethod.invoke(engine, cmd);
} catch (Exception e) {
throw new MatlabException(e);
}
}
}