org.xins.server.Function Maven / Gradle / Ivy
/*
* $Id: Function.java,v 1.161 2012/02/27 22:26:04 agoubard Exp $
*
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.server;
import java.util.concurrent.atomic.AtomicInteger;
import org.xins.common.FormattedParameters;
import org.xins.common.MandatoryArgumentChecker;
import org.xins.common.manageable.Manageable;
/**
* Base class for function implementation classes.
*
* A function can be enabled or disabled using the
* {@link #setEnabled(boolean)} method. A function that is enabled can be
* invoked, while a function that is disabled cannot. By default a function
* is enabled.
*
* @version $Revision: 1.161 $ $Date: 2012/02/27 22:26:04 $
* @author Ernst de Haan
*
* @since XINS 1.0.0
*/
public abstract class Function extends Manageable {
/**
* Call result to be returned when a function is currently disabled. See
* {@link #isEnabled()}.
*/
private static final FunctionResult DISABLED_FUNCTION_RESULT = new FunctionResult("_DisabledFunction");
/**
* The API implementation this function is part of. This field cannot be
* null
.
*/
private final API _api;
/**
* The name of this function. This field cannot be null
.
*/
private final String _name;
/**
* The version of the specification this function implements. This field
* cannot be null
.
*/
private final String _version;
/**
* Flag that indicates if this function is currently accessible.
*/
private boolean _enabled;
/**
* The total number of calls executed up until now.
*/
private AtomicInteger _callCount;
/**
* Constructs a new Function
.
*
* @param api
* the API to which this function belongs, not null
.
*
* @param name
* the name, not null
.
*
* @param version
* the version of the specification this function implements, not
* null
.
*
* @throws IllegalArgumentException
* if api == null || name == null || version == null
.
*/
protected Function(API api, String name, String version)
throws IllegalArgumentException {
// Check arguments
MandatoryArgumentChecker.check("api", api,
"name", name,
"version", version);
// Initialize fields
_api = api;
_name = name;
_version = version;
_enabled = true;
_callCount = new AtomicInteger();
// Notify the API that a Function has been added
_api.functionAdded(this);
}
/**
* Returns the API that contains this function.
*
* @return
* the {@link API}, not null
.
*/
public final API getAPI() {
return _api;
}
/**
* Returns the name of this function.
*
* @return
* the name, not null
.
*
* @since XINS 1.5.0.
*/
public final String getName() {
return _name;
}
/**
* Returns the specification version for this function.
*
* @return
* the version, not null
.
*/
final String getVersion() {
return _version;
}
/**
* Checks if this function is currently accessible.
*
* @return
* true
if this function is currently accessible,
* false
otherwise.
*
* @see #setEnabled(boolean)
*/
public final boolean isEnabled() {
return _enabled;
}
/**
* Sets if this function is currently accessible.
*
* @param enabled
* true
if this function should be accessible,
* false
if not.
*
* @see #isEnabled()
*/
public final void setEnabled(boolean enabled) {
_enabled = enabled;
}
/**
* Handles a call to this function (wrapper method). This method will call
* {@link #handleCall(CallContext context)}.
*
* @param functionRequest
* the request, never null
.
*
* @return
* the call result, never null
.
*
* @throws IllegalStateException
* if this object is currently not initialized.
*/
FunctionResult handleCall(FunctionRequest functionRequest) throws IllegalStateException {
// Check state first
assertUsable();
// Assign a call ID
int callID = _callCount.incrementAndGet();
// Check if this function is enabled
if (! _enabled) {
return DISABLED_FUNCTION_RESULT;
}
// Skipped the function call if asked to
if (functionRequest.shouldSkipFunctionCall()) {
Object inParams = new FormattedParameters(functionRequest.getParameters(), functionRequest.getDataElement());
Log.log_3516(functionRequest.getFunctionName(), inParams);
return API.SUCCESSFUL_RESULT;
}
// Construct a CallContext object
CallContext context = new CallContext(functionRequest, this, callID);
FunctionResult result;
try {
// Handle the call
result = handleCall(context);
// Make sure the result is valid
InvalidResponseResult invalidResponse = result.checkOutputParameters();
if (invalidResponse != null) {
result = invalidResponse;
String details = invalidResponse.toString();
Log.log_3501(functionRequest.getFunctionName(), callID, details);
}
} catch (Throwable exception) {
result = _api.handleFunctionException(functionRequest, callID, exception);
}
return result;
}
/**
* Handles a call to this function.
*
* @param context
* the context for this call, never null
.
*
* @return
* the result of the call, never null
.
*
* @throws Throwable
* if anything goes wrong.
*/
protected abstract FunctionResult handleCall(CallContext context)
throws Throwable;
}