/* * SALogoffActionImpl * * 12/03/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.AEF.thread.*; import com.ibm.retail.AEF.data.*; import java.rmi.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * SALogoffActionImpl is a class which the POSAutomationProvider uses to accomplish * a logoff from the SA application. * */ public class SALogoffActionImpl extends SAActionImpl { static String copyright() { return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT; } private static Log log = LogFactory.getLog(SALogoffActionImpl.class); private static AEFPerfTrace perfTrace = AEFPerfTrace.getInstance(); /** * Constructor * * @param request The ActionRequest which contains a HashMap of arguments. * * @exception AEFException */ public SALogoffActionImpl(ActionRequest request) throws AEFException { super(request); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter and -Exit SALogoffActionImpl.SALogoffActionImpl()."); log.trace(tempAEFMessage); } } /** * Perform the action represented by the ActionRequest and return an ActionResult. * * * @param request The ActionRequest which contains the classname and arguments. * @return Object The Operator instance. * @exception AEFException * Among the possible error codes are: * <br>AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_IN_PROGRESS * <br><a href="../commonerrorcodes.html">Common Errors</a> */ public Object performAction() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SALogoffActionImpl.performAction()."); log.trace(tempAEFMessage); } super.performAction(); // Call super to perform any common processing and clear any errors before we start. Object retVal = null; // If app is in secured state, and options are set to automatically do a special // signon, then create the logon action to do the special signon first. checkForSpecialSignon(); int seqResult = -1; //Check precondition that no transaction is in progress and that POS_STATE is // "MAIN" state (10). If not, throw exception. String currentState = "0"; currentState = getCurrentState(); idState = State.getState("ID"); itemEntryState = State.getState("MAIN"); repeatSignoffSubstate = Substate.getSubstate("REPEAT_SIGNOFF"); try { Transaction trans = automationProvider.getTransaction(); if (trans != null) { // We have a transaction in progress. The client must void the transaction // before logging off. String tempString = "SALogoffActionImpl.performAction(): Unable to logoff because a transaction is in progress."; AEFException tempException = new AEFException(AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_IN_PROGRESS, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } } catch (RemoteException re) { // We should never get here because we are calling locally. tempAEFMessage.setMessage("There was a remote exception thrown in SALogoffActionImpl.performAction()."); log.error(tempAEFMessage, re); } if (!currentState.equals(itemEntryState)) { // Can only logoff from the MAIN state. String tempString = "SALogoffActionImpl.performAction(): POS application not in proper state to perform logoff.\n Expected state " + itemEntryState + ", but application is in state " + currentState + "."; AEFException tempException = new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, tempString); tempAEFMessage.setMessage(tempString); log.error(tempAEFMessage, tempException); throw tempException; } else { // Application is in correct state to start preforming the logoff. seqResult = sendLogoffSequence(); if (seqResult==0) { // Successfully got to id state. if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "logoff", "<<<Detected logoff from application."); } return retVal; } } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SALogoffActionImpl.performAction()."); log.trace(tempAEFMessage); } return retVal; } /** * Send the key sequence required for a logoff. * * * @return int An integer representing the result of the key sequence. * @exception AEFException * Among the possible error codes are: * <br><a href="../commonerrorcodes.html">Common Errors</a> */ public int sendLogoffSequence() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter SALogoffActionImpl.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("SALogoffActionImpl.sendLogoffSequence() about to call performActionAndWait for part one of Signoff."); log.debug(tempAEFMessage); } 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("SALogoffActionImpl.sendLogoffSequence() about to call performActionAndWait for part two of Signoff."); log.debug(tempAEFMessage); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "logoff", ">>>Sending logoff key sequence to application."); } 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 = "SALogoffActionImpl.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.error(tempAEFMessage, tempException); throw tempException; } } } if (log.isDebugEnabled()) { tempAEFMessage.setMessage("SALogoffActionImpl.sendLogoffSequence() retVal=" + retVal); log.debug(tempAEFMessage); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit SALogoffActionImpl.sendLogoffSequence()."); log.trace(tempAEFMessage); } return retVal; } /* Instance Variables */ protected AEFAction keySequenceAction = null; protected ConditionLock lock = null; protected String idState = null; protected String itemEntryState = null; protected String repeatSignoffSubstate = null; }