AbstractOptionsParser.java
package com.github.celldynamics.quimp.plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.celldynamics.quimp.QuimpException.MessageSinkTypes;
import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
import ij.IJ;
import ij.Macro;
import ij.plugin.frame.Recorder;
/**
* This is template allows for serialize/deserialize plugin options to/from macro string.
*
* @author p.baniukiewicz
* @see AbstractPluginOptions
*/
public abstract class AbstractOptionsParser {
/**
* If true plugin is run from parametrised constructor what usually means API.
*/
public boolean apiCall;
/**
* The Constant logger.
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
protected AbstractPluginOptions options;
/**
* Indicate that plugin is run as macro from script. Blocks all UIs.
*
* <p>Use this variable in child class together with {@link #apiCall} to decide whether to show
* message in UI or console. the following rules applies:
* <ol>
* <li>errorSink = MessageSinkTypes.GUI - plugin called from IJ menu
* <li>errorSink = MessageSinkTypes.IJERROR - plugin called from macro
* <li>errorSink = MessageSinkTypes.CONSOLE - plugin called from API (but exceptions are
* re-thrown to be handled in caller code)
* </ol>
*/
protected MessageSinkTypes errorSink = MessageSinkTypes.GUI;
/**
* This default constructor must be overridden in concrete class. It is called by IJ when plugin
* instance is created. A concrete instance of {@link AbstractPluginOptions} class should be
* created there and then passed to {@link #AbstractOptionsParser(AbstractPluginOptions)}.
*/
protected AbstractOptionsParser() {
throw new NoSuchMethodError();
}
/**
* Default constructor.
*
* <p>Set {@link #apiCall} to false and assign provided options to object.
*
* @param options Reference to plugin configuration container.
*/
protected AbstractOptionsParser(AbstractPluginOptions options) {
apiCall = false;
this.options = options;
}
/**
* Constructor that allows to provide own parameter string.
*
* <p>Intended to run from API. Set {@link #apiCall} to true and {@link #errorSink} to
* {@link MessageSinkTypes#CONSOLE}.
* {@link AbstractPluginOptions} is initialised from specified string and assigned to this
* instance.
*
* @param argString parameters string like that passed in macro. If it is empty string or null
* constructor exits before deserialisation.
* @param options Reference to plugin configuration container.
* @throws QuimpPluginException on any error in plugin execution.
*/
protected AbstractOptionsParser(String argString, AbstractPluginOptions options)
throws QuimpPluginException {
apiCall = true;
this.options = options;
errorSink = MessageSinkTypes.CONSOLE;
if (argString == null || argString.isEmpty()) {
return;
}
this.options = AbstractPluginOptions.deserialize2Macro(argString, options);
}
/**
* Analyse and parse parameter string passed from IJ, macro or API.
*
* <p>If arg is empty or null, {@link #parseArgumentString(String)} tries to get it from Macro, if
* succeeds it parses it and returns true. Otherwise returns false. If arg is non-empty it assumes
* Macro call, sets {@link #errorSink} to {@link MessageSinkTypes#IJERROR} and parses arg
* returning true. {@link #apiCall} is set to false.
*
* <p>If parser succeeded, internal {@link AbstractPluginOptions} object is properly initalised
* and deserialised.
*
* @param arg parameter string
* @return return true if something has been parsed, false if input was empty or null
* @throws QuimpPluginException when parsing failed
* @see AbstractPluginOptions
* @see #getOptions()
*/
protected boolean parseArgumentString(String arg) throws QuimpPluginException {
String argString;
IJ.log(new QuimpToolsCollection().getQuimPversion());
// decode possible params passed in macro or from constructor
if (arg == null || arg.isEmpty()) { // no options passed directly to method
argString = Macro.getOptions(); // check if there are any in macro
} else {
argString = arg; // options passed here - they must be in the same format as in macro
}
if (argString != null && !argString.isEmpty()) { // something passed
errorSink = MessageSinkTypes.IJERROR; // set errors to ij, we are in macro mode
options = AbstractPluginOptions.deserialize2Macro(argString, options);
return true;
} else {
return false;
}
}
/**
* Return {@link #options}.
*
* @return the options
*/
public AbstractPluginOptions getOptions() {
return options;
}
/**
* Helper, show macro parameters string if recorder is active.
*
* <p>Perform serialisation of {@link AbstractPluginOptions} object composed with this
* class.
*
* @param commandName name of the command to be displayed in IJ. Usually it is string taken from
* plugins.conf
*/
protected void publishMacroString(String commandName) {
// check whether config file name is provided or ask user for it
if (options != null) { // for some mockito tests
logger.debug("Internal options " + options.serialize2Macro());
}
if (Recorder.record) {
Recorder.setCommand(commandName);
Recorder.recordOption(AbstractPluginOptions.KEY, options.serialize2Macro());
Recorder.saveCommand();
}
}
}