matlabcontrol.LoggingMatlabProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of matconsolectl Show documentation
Show all versions of matconsolectl Show documentation
MatConsoleCtl - control MATLAB from Java
/*
* Code licensed under new-style BSD (see LICENSE).
* All code up to tags/original: Copyright (c) 2013, Joshua Kaplan
* All code after tags/original: Copyright (c) 2016, DiffPlug
*/
package matlabcontrol;
import java.lang.reflect.Array;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Wraps around a {@link MatlabProxy} to provide a log of interactions. The data is not altered. This logger is useful
* for determining the Java types and structure of data returned from MATLAB.
*
* Interaction with all methods, except those defined in {@code Object} and not overridden, is logged. Entering a
* method, exiting a method, and throwing an exception are logged. Method parameters and return values are logged. The
* contents of a returned array will be recursively explored and its contents logged. As is convention, all of these
* interactions are logged at {@code Level.FINER}. If the logging system has not been otherwise configured, then the
* {@code ConsoleHandler} which prints log messages to the console will not show these log messages as their level is
* too low. To configure the {@code ConsoleHandler} to show these log messages, call {@link #showInConsoleHandler()}.
*
* This class is unconditionally thread-safe.
*
* @since 4.1.0
*
* @author Joshua Kaplan
*/
public final class LoggingMatlabProxy extends MatlabProxy {
private static final String CLASS_NAME = LoggingMatlabProxy.class.getName();
private static final Logger LOGGER = Logger.getLogger(CLASS_NAME);
static {
LOGGER.setLevel(Level.FINER);
}
private final MatlabProxy _delegate;
/**
* Constructs the logging proxy. All methods defined in {@code MatlabProxy} will be delegated to
* {@code delegateProxy}.
*
* @param delegateProxy
*/
public LoggingMatlabProxy(MatlabProxy delegateProxy) {
super(delegateProxy.getIdentifier(), delegateProxy.isExistingSession());
_delegate = delegateProxy;
}
/**
* Configures the {@code ConsoleHandler} responsible for showing logging records to show the records that are
* logged by this proxy. This behavior is useful if you have not otherwise configured logging in your application.
*/
public static void showInConsoleHandler() {
for (Handler handler : Logger.getLogger("").getHandlers()) {
if (handler instanceof ConsoleHandler) {
handler.setLevel(Level.FINER);
}
}
}
private static abstract class Invocation {
final String name;
final Object[] args;
public Invocation(String name, Object... args) {
this.name = name;
this.args = args;
}
}
private static abstract class VoidThrowingInvocation extends Invocation {
public VoidThrowingInvocation(String name, Object... args) {
super(name, args);
}
public abstract void invoke() throws MatlabInvocationException;
}
private static abstract class VoidInvocation extends Invocation {
public VoidInvocation(String name, Object... args) {
super(name, args);
}
public abstract void invoke();
}
private static abstract class ReturnThrowingInvocation extends Invocation {
public ReturnThrowingInvocation(String name, Object... args) {
super(name, args);
}
public abstract T invoke() throws MatlabInvocationException;
}
private static abstract class ReturnInvocation extends Invocation {
public ReturnInvocation(String name, Object... args) {
super(name, args);
}
public abstract T invoke();
}
private static abstract class ReturnBooleanInvocation extends Invocation {
public ReturnBooleanInvocation(String name, Object... args) {
super(name, args);
}
public abstract boolean invoke();
}
private void invoke(VoidThrowingInvocation invocation) throws MatlabInvocationException {
LOGGER.entering(CLASS_NAME, invocation.name, invocation.args);
try {
invocation.invoke();
LOGGER.exiting(CLASS_NAME, invocation.name);
} catch (MatlabInvocationException e) {
LOGGER.throwing(CLASS_NAME, invocation.name, e);
LOGGER.exiting(CLASS_NAME, invocation.name);
throw e;
}
}
private void invoke(VoidInvocation invocation) {
LOGGER.entering(CLASS_NAME, invocation.name, invocation.args);
invocation.invoke();
LOGGER.exiting(CLASS_NAME, invocation.name);
}
private T invoke(ReturnThrowingInvocation invocation) throws MatlabInvocationException {
T data;
LOGGER.entering(CLASS_NAME, invocation.name, invocation.args);
try {
data = invocation.invoke();
LOGGER.exiting(CLASS_NAME, invocation.name, formatResult(data));
} catch (MatlabInvocationException e) {
LOGGER.throwing(CLASS_NAME, invocation.name, e);
LOGGER.exiting(CLASS_NAME, invocation.name);
throw e;
}
return data;
}
private T invoke(ReturnInvocation invocation) {
LOGGER.entering(CLASS_NAME, invocation.name, invocation.args);
T data = invocation.invoke();
LOGGER.exiting(CLASS_NAME, invocation.name, formatResult(data));
return data;
}
private boolean invoke(ReturnBooleanInvocation invocation) {
LOGGER.entering(CLASS_NAME, invocation.name, invocation.args);
boolean data = invocation.invoke();
LOGGER.exiting(CLASS_NAME, invocation.name, "boolean: " + data);
return data;
}
@Override
public void eval(final String command) throws MatlabInvocationException {
this.invoke(new VoidThrowingInvocation("eval(String)", command) {
@Override
public void invoke() throws MatlabInvocationException {
_delegate.eval(command);
}
});
}
@Override
public Object[] returningEval(final String command, final int nargout) throws MatlabInvocationException {
return this.invoke(new ReturnThrowingInvocation
© 2015 - 2024 Weber Informatics LLC | Privacy Policy