/* * GSAForcedLogoffActionImpl * * 07/01/2003 * * 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; /** * GSAForcedLogoffActionImpl is a class which the POSAutomationProvider * uses to accomplish a forced logoff within the GSA application. * */ public class GSAForcedLogoffActionImpl extends GSAActionImpl { static String copyright() { return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT; } /** * 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: * <br>AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR * <br><a href="../commonerrorcodes.html">Common Errors</a> */ public GSAForcedLogoffActionImpl(ActionRequest request) throws AEFException { super(request); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSAForcedLogoffActionImpl.GSAForcedLogoffActionImpl()."); log.trace(tempAEFMessage); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSAForcedLogoffActionImpl.GSAForcedLogoffActionImpl()."); 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: * <br>AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_CANNOT_BE_VOIDED * <br><a href="../commonerrorcodes.html">Common Errors</a> */ public Object performAction() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSAForcedLogoffActionImpl.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 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 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) { throw(e); } else { if (log.isInfoEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.performAction timeout after handleError()."); log.info(tempAEFMessage); } } } } // If in state SIGNOFF then send ENTER key. if (getCurrentState().equalsIgnoreCase(signOffState)) { try { sendEnterSequence(); } 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.isInfoEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.performAction timeout after sendEnterSequence()."); log.info(tempAEFMessage); } } } } // If in ID state then stop if (getCurrentState().equalsIgnoreCase(idState)) { break; // We are at the desired state. } else // try to log off! { try { automationProvider.logoff(); } 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.isInfoEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.performAction timeout after sendLogoffSequence()."); log.info(tempAEFMessage); } } } } } // 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) { throw(e); } else { if (log.isInfoEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.performAction timeout after handleError()."); log.info(tempAEFMessage); } } } } // Wait to get into the ID state. String[] states = { idState }; waitForStates(states); } catch (AEFException e) { tempAEFMessage.setMessage("There was an AEF exception thrown in performAction of GSAForcedLogoffActionImpl."); log.error(tempAEFMessage, e); throw e; } catch (RemoteException re) { // Not expected to get here since we are calling locally. tempAEFMessage.setMessage("There was a remote exception thrown in performAction of GSAForcedLogoffActionImpl."); log.error(tempAEFMessage, re); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSAForcedLogoffActionImpl.performAction()."); log.trace(tempAEFMessage); } return null; } /** * Sends the Enter key sequence. * * @return int Integer value representing the result of the key sequence. * 0 = Were are in the ID State. * <0 = There was an error. * @exception com.ibm.retail.AEF.util.AEFException * Among the possible AEFException error codes are: * <br><a href="../commonerrorcodes.html">Common Errors</a> */ private int sendEnterSequence() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSAForcedLogoffActionImpl.sendEnterSequence()."); log.trace(tempAEFMessage); } int retVal = -1; AEFAction keySequenceAction = null; ConditionLock lock = new ConditionLock(); // Send the second part of the logoff sequence and check for errors. args.clear(); args.put("SEQUENCE_ID", "logoff2"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); Condition[] goodConditions2 = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, State.getState("ID")) }; if (log.isDebugEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.sendEnterSequence() 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); if (retVal < 0) { tempAEFMessage.setMessage("An AEF exception was thrown in GSAForcedLogoffActionImpl.sendEnterSequence()"); log.trace(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } if (log.isDebugEnabled()) { tempAEFMessage.setMessage("GSAForcedLogoffActionImpl.sendEnterSequence() retVal=" + retVal); log.debug(tempAEFMessage); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSAForcedLogoffActionImpl.sendEnterSequence()."); log.trace(tempAEFMessage); } return retVal; } /** * Initialize the state variables for GSA. * */ private void initializeStates() { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSAForcedLogoffActionImpl.initializeStates()."); log.trace(tempAEFMessage); } clearState = State.getState("CLEAR"); idState = State.getState("ID"); signOffState = State.getState("SIGNOFF"); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSAForcedLogoffActionImpl.initializeStates()."); log.trace(tempAEFMessage); } } /** * Calls the Error Handler to try to clear an error. * * @return int Integer value representing the result of the key sequence. * @exception com.ibm.retail.AEF.util.AEFException * Among the possible AEFException error codes are: * <br>AEFConst.APPLICATION_NOT_IN_PROPER_STATE * <br>AEFConst.OPERATION_TIMEOUT * <br>AEFConst.PROCEDURE_NOT_ALLOWED, AEFConst.TRANSACTION_CANNOT_BE_VOIDED * <br>AEFConst.WAIT_INTERRUPTED * <br><a href="../commonerrorcodes.html">Common Errors</a> */ public int handleError() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSAForcedLogoffActionImpl.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))); lock = new ConditionLock(); errorHandler = new AEFErrorHandler("There was an error in GSAForcedLogoffActionImpl.handleError()"); retVal = errorHandler.handleError(lock, keySequenceAction, BadConditionsImpl.getInstance().getLogicalOpposite(), BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("An AEF exception was thrown in GSAForcedLogoffActionImpl.handleError()"); log.trace(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSAForcedLogoffActionImpl.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 signOffState = null; private static Log log = LogFactory.getLog(GSAForcedLogoffActionImpl.class); }