org.n52.matlab.control.LoggingMatlabProxy Maven / Gradle / Ivy
The newest version!
package org.n52.matlab.control;
/*
* Copyright (c) 2013, Joshua Kaplan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* - Neither the name of matlabcontrol nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
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