/*
* SAForcedLogoffActionImpl
*
* 12/27/2002
*
* Copyright:
* Licensed Materials - Property of IBM
* "Restricted Materials of IBM"
* 5724-AEF
* (C) Copyright IBM Corp. 2003.
*
* %W% %E%
*/
package com.ibm.retail.AEF.action;
import com.ibm.retail.AEF.automation.*;
import com.ibm.retail.AEF.util.*;
import com.ibm.retail.si.util.*;
import com.ibm.retail.si.Copyright;
import com.ibm.retail.AEF.factory.*;
import com.ibm.retail.AEF.thread.*;
import com.ibm.retail.AEF.data.*;
import com.ibm.retail.AEF.session.*;
import java.util.*;
import java.rmi.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* SAForcedLogoffActionImpl is a class which the POSAutomationProvider
* uses to accomplish a force logoff within the SA application.
*
*/
public class SAForcedLogoffActionImpl extends SAActionImpl
{
static String copyright()
{ return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT; }
private static AEFPerfTrace perfTrace = AEFPerfTrace.getInstance();
/**
* Constructor
*
* @param request The ActionRequest which contains a HashMap of arguments.
*
* @exception com.ibm.retail.AEF.util.AEFException
* Among the possible AEFException error codes are:
*
AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR
*
Common Errors
*/
public SAForcedLogoffActionImpl(ActionRequest request) throws AEFException
{
super(request);
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter and -Exit SAForcedLogoffActionImpl.SAForcedLogoffActionImpl().");
log.trace(tempAEFMessage);
}
}
/**
* Tries to void the current transaction (if any) and return the application
* to the ID state
*
* @return Object N/A (null).
* @exception com.ibm.retail.AEF.util.AEFException
* Among the possible AEFException error codes are:
*
AEFConst.APPLICATION_NOT_IN_PROPER_STATE
*
AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
AEFConst.MANAGER_OVERRIDE_REQUIRED
*
Common Errors
*/
public Object performAction() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.performAction().");
log.trace(tempAEFMessage);
}
super.performAction(); // Call super to perform any common processing and clear any errors before we start.
boolean salesTranInProgress = false;
boolean nonSalesTranInProgress = false;
Transaction trans = null;
ObjectDetector detector = null;
try
{
// Check for a "partial" transaction which was started, but no items have been sold.
trans = automationProvider.getTransaction();
if (trans != null)
{
if (trans.getTransactionInfo().getTransactionID() == null)
{
// Clear the partial transaction object.
detector = ((DetectorAccess)(SessionContext.getSession())).getTransactionDetector();
detector.reset();
automationProvider.setTransaction(null);
}
}
// Check the condition that we are in the middle of a transaction.
salesTranInProgress = getBooleanProviderProperty(WorkstationStatusProperties.CATEGORY, WorkstationStatusProperties.SALES_TRANSACTION_IN_PROGRESS);
nonSalesTranInProgress = getBooleanProviderProperty(WorkstationStatusProperties.CATEGORY, WorkstationStatusProperties.NONSALES_TRANSACTION_IN_PROGRESS);
if (salesTranInProgress || nonSalesTranInProgress)
{
// We are in the middle of the transaction so lets void it.
automationProvider.voidCurrentTransaction();
}
// Now try to return the application to the "ID" State.
// First get all the states and sub-states from the config files.
initializeStates();
// Loop several times through the state test to ensure that we do not miss an escape route.
for (int i = 0; i < 2; i++)
{
// If in "REPEAT SIGNOFF" substate send
if (getCurrentSubstate().equalsIgnoreCase(repeatSignoffSubstate))
{
try
{
// We are in the middle of the transaction so void it.
sendSignoffSequence();
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue,
// we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
throw(e);
}
else
{
if (log.isDebugEnabled())
{
log.debug("SAForcedLogoffActionImpl.performAction timeout during sendSignoffSequence().");
}
}
}
}
// If in states so pswd, standalone or autosign throw invalid state exception.
if (getCurrentState().equalsIgnoreCase(soPasswordState) || getCurrentState().equalsIgnoreCase(standaloneState) || getCurrentState().equalsIgnoreCase(autoSignState))
{
String tempString = "SAForcedLogoffActionImpl.performAction(): POS application not in proper state to do a Forced Logoff.\n Application is in state " + getCurrentState() + ".";
AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString);
tempAEFMessage.setMessage(tempString);
log.error(tempAEFMessage, tempException);
throw tempException;
}
// If in spec-so state send to get us to override state.
if (getCurrentState().equalsIgnoreCase(securedState))
{
try
{
sendSpecsoToOverrideSequence(true);
if (getCurrentState().equalsIgnoreCase(securedState))
{
String tempString = "SAForcedLogoffActionImpl.performAction(): POS application not in proper state to do a Forced Logoff.\n Application is in state " + getCurrentState() + ".";
AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString);
throw tempException;
}
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during sendSpecsoToOverrideSequence().");
log.debug(tempAEFMessage);
}
}
}
}
// If in override state send {password}
if (getCurrentState().equalsIgnoreCase(overrideState))
{
try
{
String autoMgrOverride = automationProvider.getProperty(POSAutomationProvider.AUTO_MGR_OVERRIDE);
if (autoMgrOverride.equalsIgnoreCase("true"))
{
automationProvider.managerOverride();
}
else
{
AEFException ex = new AEFException(AEFConst.MANAGER_OVERRIDE_REQUIRED,
0,
"SAForcedLogoffActionImpl.performAction(): A manager override is required for this operation but automatic override is not allowed.");
throw ex;
}
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during managerOverride().");
log.debug(tempAEFMessage);
}
}
}
}
// If in state enter, wait to get out of the state .
if (getCurrentState().equalsIgnoreCase(enterState))
{
try
{
waitForStateChange(enterState);
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during waitForStateChange().");
log.debug(tempAEFMessage);
}
}
}
}
// If in state clear then call the error handler.
if (getCurrentState().equalsIgnoreCase(clearState))
{
try
{
handleError();
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during handleError().");
log.debug(tempAEFMessage);
}
}
}
}
// If in state password then send clear sequence.
if (getCurrentState().equalsIgnoreCase(passwordState))
{
try
{
sendClearSequence(true);
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during sendClearSequence().");
log.debug(tempAEFMessage);
}
}
}
}
// If in Main state send
if (getCurrentState().equalsIgnoreCase(mainState))
{
try
{
sendLogoffSequence();
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during sendLogoffSequence().");
log.debug(tempAEFMessage);
}
}
}
}
// If in ID state then stop
if (getCurrentState().equalsIgnoreCase(idState))
{
break; // We are at the desired state.
}
} // End of For Loop
// If we are out of the loop with an error condition, lets try to clear it one last time.
if (getCurrentState().equalsIgnoreCase(clearState))
{
try
{
handleError();
}
catch (AEFException e)
{
// Check to see if we timed out. If so log the error but continue, we may be in a state which we can fix below.
if (e.getErrorCode() != AEFConst.OPERATION_TIMEOUT)
{
tempAEFMessage.setMessage("An AEF exception was thrown in SAForcedLogoffActionImpl.performAction()");
log.error(tempAEFMessage, e);
throw(e);
}
else
{
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.performAction timeout during handleError().");
log.debug(tempAEFMessage);
}
}
}
}
// Wait to get into the ID state.
String[] states =
{
idState
};
waitForStates(states);
}
catch (RemoteException re)
{
// Not expected to get here since we are calling locally.
tempAEFMessage.setMessage("There was a remote exception thrown in SAForcedLogoffActionImpl.performAction().");
log.error(tempAEFMessage, re);
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit SAForcedLogoffActionImpl.performAction().");
log.trace(tempAEFMessage);
}
return null;
}
/**
* Sends the key sequence required to logoff an operator.
*
* @result int Integer value representing the result of the key sequence.
* 0 = Were are in the ID State.
* -1 = Clear State
* -2 = B013
* @exception com.ibm.retail.AEF.util.AEFException
* Among the possible AEFException error codes are:
*
AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
AEFConst.APPLICATION_NOT_IN_PROPER_SUBSTATE
*
Common Errors
*/
public int sendLogoffSequence() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.sendLogoffSequence().");
log.trace(tempAEFMessage);
}
int retVal = -1;
lock = new ConditionLock();
// Send the first part of the logoff sequence and check for errors.
args.clear();
args.put("SEQUENCE_ID", "logoff1");
keySequenceAction = (AEFAction) (actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
Condition[] goodConditions1 =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_SUB_STATE, repeatSignoffSubstate),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, idState)
};
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.sendLogoffSequence() about to call performActionAndWait for part one of Signoff.");
log.debug(tempAEFMessage);
}
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
">>>Sending logoff key sequence to application.");
}
retVal = lock.performActionAndWait("wait-for-id-state",
keySequenceAction,
goodConditions1,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout());
if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Send Logoff Sequence Error Part 1");
retVal = errorHandler.handleError(lock, keySequenceAction, goodConditions1, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal);
}
if (retVal >= 0) // The last command completed and any error were handled.
{
if (getCurrentState().equalsIgnoreCase(idState) == false) // We are not in the desired state.
{
String substateNow = getCurrentSubstate();
if (substateNow.equalsIgnoreCase(repeatSignoffSubstate)) // Send the second part of the signoff sequence.
{
args.clear();
args.put("SEQUENCE_ID", "logoff2");
keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
Condition[] goodConditions2 =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY,
POSDeviceProperties.POS_STATE,
idState)
};
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.sendLogoffSequence() about to call performActionAndWait for part two of Signoff.");
log.debug(tempAEFMessage);
}
retVal = lock.performActionAndWait("wait-for-id-state",
keySequenceAction,
goodConditions2,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout());
if (retVal < 0)
{
AEFErrorHandler errorHandler = new AEFErrorHandler("Send Logoff Sequence Error Part 2");
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions2,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
}
}
else // We are not where we think we should be!
{
String tempString = "SAForcedLogoffActionImpl.sendLogoffSequence(): POS application not in proper substate to perform logoff.\n Expected substate " + repeatSignoffSubstate + ", but application is in substate " + substateNow + ".";
AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_SUBSTATE, 0, tempString);
tempAEFMessage.setMessage(tempString);
log.debug(tempAEFMessage, tempException);
throw tempException;
}
}
}
if (log.isDebugEnabled())
{
tempAEFMessage.setMessage("SAForcedLogoffActionImpl.sendLogoffSequence() retVal=" + retVal);
log.debug(tempAEFMessage);
}
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
"<<AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
Common Errors
*/
public int sendSpecsoToOverrideSequence(boolean wait) throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.sendSpecsoToOverrideSequence().");
log.trace(tempAEFMessage);
}
int retVal = -1;
AEFErrorHandler errorHandler = null;
args.clear();
args.put("SEQUENCE_ID", "specialSignonToOverride");
keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
if (wait)
{
AbstractPropertyCondition[] conditions =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, clearState)
};
lock = new ConditionLock();
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
">>>Sending signon key to application.");
}
retVal = lock.performActionAndWait("wait-for-state-OVERRIDE",keySequenceAction, conditions, getTimeout());
if (retVal < 0)
{
errorHandler = new AEFErrorHandler("There was an error in SAForcedLogoffActionImpl.sendSpecsoToOverrideSequence()");
retVal = errorHandler.handleError(lock, keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal);
if (retVal < 0)
{
tempAEFMessage.setMessage("There was an exception in SAForcedLogoffActionImpl.sendSpecsoToOverrideSequence()");
log.error(tempAEFMessage, errorHandler.getAllExceptions());
throw errorHandler.getAllExceptions();
}
}
}
else
{
keySequenceAction.performAction();
}
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
"<<AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
Common Errors
*/
public int sendClearSequence(boolean wait) throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.sendClearSequence().");
log.trace(tempAEFMessage);
}
int retVal = -1;
AEFErrorHandler errorHandler = null;
args.clear();
args.put("SEQUENCE_ID", "clear-error");
keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
if (wait)
{
AbstractPropertyCondition[] conditions =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, idState),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, overrideState)
};
lock = new ConditionLock();
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
">>>Sending clear key to application.");
}
retVal = lock.performActionAndWait("wait-for-state-main",keySequenceAction, conditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout());
if (retVal < 0)
{
errorHandler = new AEFErrorHandler("There was an error in SAForcedLogoffActionImpl.sendClearSequence()");
retVal = errorHandler.handleError(lock,
keySequenceAction,
conditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
if (retVal < 0)
{
tempAEFMessage.setMessage("There was an exception in SAForcedLogoffActionImpl.sendClearSequence()");
log.error(tempAEFMessage, errorHandler.getAllExceptions());
throw errorHandler.getAllExceptions();
}
}
}
else
{
keySequenceAction.performAction();
}
if (perfTrace.isEnabled(AEFPerfTrace. COARSE))
{
perfTrace.reportTimer(AEFPerfTrace. COARSE,
sessionID,
"forceLogoff",
"<<AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
Common Errors
*/
public int sendSignoffSequence() throws AEFException
{
int retVal = -1;
AEFErrorHandler errorHandler = null;
args.clear();
args.put("SEQUENCE_ID", "logoff2");
keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
Condition[] goodConditions =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, idState)
};
lock = new ConditionLock();
retVal = lock.performActionAndWait("wait-for-id-state",
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout());
if (retVal < 0)
{
errorHandler = new AEFErrorHandler("Send Repeat Logoff Sequence Error");
retVal = errorHandler.handleError(lock,
keySequenceAction,
goodConditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
}
return retVal;
}
/**
* Initialize the state variables for SA.
*
* @result void
*/
private void initializeStates()
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.initializeStates().");
log.trace(tempAEFMessage);
}
// Get the values for all the SA application states.
clearState = State.getState("CLEAR");
idState = State.getState("ID");
passwordState = State.getState("PASSWORD");
soPasswordState = State.getState("SO_PASSWORD");
securedState = State.getState("SECURED");
overrideState = State.getState("OVERRIDE");
mainState = State.getState("MAIN");
standaloneState = State.getState("STANDALONE");
autoSignState = State.getState("AUTOSIGN");
enterState = State.getState("ENTER");
repeatSignoffSubstate = Substate.getSubstate("REPEAT_SIGNOFF");
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit SAForcedLogoffActionImpl.initializeStates().");
log.trace(tempAEFMessage);
}
}
/**
* Calls the Error Handler to try to clear an error.
*
* @result int Integer value representing the result of the key sequence.
* @exception com.ibm.retail.AEF.util.AEFException
* Among the possible AEFException error codes are:
*
AEFConst.APPLICATION_NOT_IN_PROPER_STATE
*
AEFConst.OPERATION_TIMEOUT
*
AEFConst.WAIT_INTERRUPTED
*
Common Errors
*/
public int handleError() throws AEFException
{
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("+Enter SAForcedLogoffActionImpl.handleError().");
log.trace(tempAEFMessage);
}
int retVal = -1;
AEFErrorHandler errorHandler = null;
args.clear();
args.put("SEQUENCE_ID", "clear-error");
keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args)));
AbstractPropertyCondition[] conditions =
{
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, mainState),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, idState),
new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, overrideState)
};
lock = new ConditionLock();
errorHandler = new AEFErrorHandler("There was an error in SAForcedLogoffActionImpl.handleError()");
retVal = errorHandler.handleError(lock,
keySequenceAction,
conditions,
BadConditionsImpl.getInstance().getBadConditions(),
getTimeout(),
retVal);
if (retVal < 0)
{
tempAEFMessage.setMessage("There was an exception in SAForcedLogoffActionImpl.handleError()");
log.error(tempAEFMessage, errorHandler.getAllExceptions());
throw errorHandler.getAllExceptions();
}
if (log.isTraceEnabled())
{
tempAEFMessage.setMessage("-Exit SAForcedLogoffActionImpl.handleError().");
log.trace(tempAEFMessage);
}
return retVal;
}
// Instance Variables
protected AEFAction keySequenceAction = null;
protected ConditionLock lock = null;
protected String idState = null;
protected String clearState = null;
protected String passwordState = null;
protected String soPasswordState = null;
protected String securedState = null;
protected String overrideState = null;
protected String mainState = null;
protected String standaloneState = null;
protected String autoSignState = null;
protected String enterState = null;
protected String repeatSignoffSubstate = null;
private static Log log = LogFactory.getLog(SAForcedLogoffActionImpl.class);
}