/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2002
* Copyright by ESO (in the framework of the ALMA collaboration)
* and Cosylab 2002, All rights reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package alma.ACS.jbaci;
import alma.ACS.CBDescIn;
import alma.ACS.CBDescOut;
import alma.ACS.CBvoid;
import alma.ACS.Callback;
import alma.ACSErr.Completion;
import alma.ACSErrTypeCommon.wrappers.AcsJCouldntPerformActionEx;
import alma.acs.exceptions.AcsJException;
/**
* BACI action.
* @author <a href="mailto:matej.sekoranjaATcosylab.com">Matej Sekoranja</a>
* @version $id$
*/
public abstract class BACIAction implements PrioritizedRunnable {
/**
* Action priority.
*/
protected BACIPriority priority;
/**
* Executor.
*/
protected PrioritizedExecutor executor;
/**
* Callback out descriptor.
*/
protected CBDescOut descOut;
/**
* Callback.
*/
protected Callback callback;
/**
* Callback dispatcher (used to dispatch non-CBvoid callbacks).
*/
protected CallbackDispatcher callbackDispatcher;
/**
* Completion.
*/
protected Completion completion;
/**
* Return value.
*/
protected Object returnValue;
/**
* Constructor of NORMAL priority action (CBvoid callback).
* @param executor executor to be used to execute action.
* @param callback action callback.
* @param descIn action callback in descriptor.
*/
public BACIAction(PrioritizedExecutor executor, CBvoid callback, CBDescIn descIn)
{
this(executor, callback, descIn, (CallbackDispatcher)null);
}
/**
* Constructor of NORMAL priority action.
* @param executor executor to be used to execute action.
* @param callback action callback.
* @param descIn action callback in descriptor.
* @param callbackDispatcher callback dispatcher (value dependend).
*/
public BACIAction(PrioritizedExecutor executor,
Callback callback, CBDescIn descIn,
CallbackDispatcher callbackDispatcher)
{
this(executor, callback, descIn, callbackDispatcher, BACIPriority.NORMAL);
}
/**
* Constructor.
* @param executor executor to be used to execute action.
* @param callback action callback.
* @param descIn action in descriptor.
* @param priority action priority.
*/
public BACIAction(PrioritizedExecutor executor, CBvoid callback, CBDescIn descIn, BACIPriority priority)
{
this(executor, callback, descIn, null, priority);
}
/**
* Constructor.
* @param executor executor to be used to execute action.
* @param callback action callback.
* @param descIn action in descriptor.
* @param callbackDispatcher callback dispatcher (value dependend).
* @param priority action priority.
*/
public BACIAction(PrioritizedExecutor executor,
Callback callback, CBDescIn descIn,
CallbackDispatcher callbackDispatcher, BACIPriority priority)
{
this.executor = executor;
this.callback = callback;
this.callbackDispatcher = callbackDispatcher;
this.priority = priority;
descOut = generateCBDescOut(descIn);
}
/**
* @see alma.ACS.jbaci.PrioritizedRunnable#getPriority()
*/
public BACIPriority getPriority() {
return priority;
}
/**
* Generates callback out descriptor from in descriptor.
* @param descIn callback in descriptor.
* @return generated callback out descriptor.
*/
protected static CBDescOut generateCBDescOut(CBDescIn descIn)
{
return new CBDescOut(0, descIn.id_tag);
}
/**
* NOT TO BE CHANGED.
*/
public final void run()
{
try
{
returnValue = execute();
// generate no-error completion
if (completion == null)
completion = CompletionUtil.generateNoErrorCompletion();
}
catch (AcsJException ex)
{
AcsJCouldntPerformActionEx cpa = new AcsJCouldntPerformActionEx(ex);
completion = CompletionUtil.generateCompletion(cpa);
}
catch (Throwable th)
{
AcsJCouldntPerformActionEx cpa =
new AcsJCouldntPerformActionEx("Exception caught invoking BACI action method.", th);
completion = CompletionUtil.generateCompletion(cpa);
}
finally
{
if (!dispatch())
{
// TODO log (if there are retries impl., only the last...)
}
}
}
/**
* Dispatch method.
* @return <code>true</code> if successfully dispatched.
*/
protected boolean dispatch()
{
// TODO should this be done in BACIDispatcher (we have priorities...)
// TODO retries (or CORBA already does that)
try
{
if (callbackDispatcher == null)
{
return CBvoidCallbackDispatcher.getInstance().dispatchCallback(
CallbackDispatcher.DONE_TYPE,
null, callback,
completion, descOut);
}
else
return callbackDispatcher.dispatchCallback(CallbackDispatcher.DONE_TYPE,
returnValue, callback,
completion, descOut);
}
catch (Throwable th)
{
return false;
}
}
/**
* Action to be executed - implement it.
* If <code>completion</code> field is left to <code>null</code> (by this method),
* this class will create a no-error completion with current timestamp.
* Use <code>alma.ACS.jbaci.CompletionUtil</code> class to generate no-error completion.
* @return value to be send via callback, can be <code>null</code>.
*/
public abstract Object execute() throws AcsJException;
/**
* Sumbit action to be <code>BACIExecutor<code> to be executed.
*/
public void submit()
{
executor.execute(this);
}
}