/* * GSALogonActionImpl * * 06/06/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.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; /** * GSALogonActionImpl is a class which the POSAutomationProvider uses to accomplish * a logon onto the GSA application. * */ public class GSALogonActionImpl extends GSAActionImpl { static String copyright() { return com.ibm.retail.si.Copyright.IBM_COPYRIGHT_SHORT;} private static AEFPerfTrace perfTrace = AEFPerfTrace.getInstance(); private static Log log = LogFactory.getLog(GSALogonActionImpl.class); /** * 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 GSALogonActionImpl(ActionRequest request) throws AEFException { super(request); if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSALogonActionImpl.GSALogonActionImpl()."); log.trace(tempAEFMessage); } OperatorIdentifier opId = (OperatorIdentifier)(request.getArguments()); id = opId.getID(); password = opId.getPassword(); newPassword = opId.getNewPassword(); if (id == null || id.length() == 0) { id = AppLogons.getID(sessionID); } if (password == null || password.length() == 0) { password = AppLogons.getPassword(sessionID); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSALogonActionImpl.GSALogonActionImpl()."); 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 AEFException error codes are: * <br>AEFConst.INVALID_ARGUMENT, AEFConst.NEW_PASSWORD_PROHIBITED * <br>AEFConst.APPLICATION_NOT_IN_PROPER_STATE */ public Object performAction() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSALogonActionImpl.performAction()."); log.trace(tempAEFMessage); } super.performAction(); // Call super to perform any common processing and clear any errors before we start. if (newPassword != null && newPassword.length() > 0) { AEFException tempException = new AEFException(AEFConst.INVALID_ARGUMENT, AEFConst.NEW_PASSWORD_PROHIBITED, "GSALogonActionImpl.performAction(): Change password function not implemented."); tempAEFMessage.setMessage("An AEF exception was thrown in GSALogonActionImpl.performAction()."); log.error(tempAEFMessage, tempException); throw tempException; } Operator operator = null; try { detector = ((DetectorAccess)(SessionContext.getSession())).getOperatorDetector(); // If we are not in the ID state then throw an exception. String idState = State.getState("ID"); String currentState = getCurrentState(); if (!currentState.equals(idState)) { // Not in valid state for signon. throw new AEFException(AEFConst.APPLICATION_NOT_IN_PROPER_STATE, 0, "GSALogonActionImpl.performAction(): POS application not in proper state to perform logon.\n Expected state " + idState + ", but application is in state " + currentState + "."); } else { // Application is in correct state to start performing the logon. if (sendIDSequence() == 0) { sendPasswordSequence(); } operator = waitForOperator(); operator.getInfo().setPassword(password); } } catch (AEFException e) { tempAEFMessage.setMessage("There was an AEF exception thrown in performAction of GSALogonActionImpl."); log.error(tempAEFMessage, e); throw e; } catch (RemoteException re) { // We should never get here because we are calling locally. tempAEFMessage.setMessage("There was a remote exception thrown in performAction of GSALogonActionImpl."); log.error(tempAEFMessage, re); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSALogonActionImpl.performAction()."); log.trace(tempAEFMessage); } return operator; } /** * Sends the key sequence for entering the operator id. * * @return int The condition that satisfied the wait. * @exception AEFException * Among the possible AEFException error codes are: * <br>AEFConst.CONFIG_ERROR, AEFConst.NO_DEFAULT_ID_CONFIGURED */ private int sendIDSequence() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSALogonActionImpl.sendIDSequence()."); log.trace(tempAEFMessage); } int retVal = -1; if ( id == null || id.length() == 0) { // Error, unable to lookup default id for terminal number. AEFException tempException = new AEFException(AEFConst.CONFIG_ERROR, AEFConst.NO_DEFAULT_ID_CONFIGURED, "GSALogonActionImpl: Default ID and/or password not configured for terminal " + sessionID + ", unable to perform logon.\nSee applogon.properties for id/password configuration."); tempAEFMessage.setMessage("An AEF exception was thrown in GSALogonActionImpl.sendIDSequence()."); log.error(tempAEFMessage, tempException); throw tempException; } args.clear(); args.put("%0", id); args.put("SEQUENCE_ID", "id"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); Condition[] goodConditions = { new PropertyEqualsCondition(POSDeviceProperties.CATEGORY, POSDeviceProperties.POS_STATE, State.getState("PASSWORD")) }; lock = new ConditionLock(); // Save any current operator instance number so we are sure to only get an operator // created after this key sequence is sent. instanceNumber = detector.getInstanceNumber(); retVal = lock.performActionAndWait("wait-for-password-state", keySequenceAction, GSANormalConditionsImpl.getInstance().getShortConditions(goodConditions), BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { AEFErrorHandler errorHandler = new AEFErrorHandler("Send Signon ID Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, goodConditions, BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("An AEF exception was thrown in GSALogonActionImpl.sendIDSequence()."); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } if (log.isDebugEnabled()) { tempAEFMessage.setMessage("GSALogonActionImpl.sendIDSequence() returning : " + retVal); log.debug(tempAEFMessage); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSALogonActionImpl.sendIDSequence()."); log.trace(tempAEFMessage); } return(retVal); } /** * Sends the key sequence for entering the operator password. * * * @exception AEFException * Among the possible AEFException error codes are: * <br>AEFConst.CONFIG_ERROR, AEFConst.NO_DEFAULT_ID_CONFIGURED */ private void sendPasswordSequence() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSALogonActionImpl.sendPasswordSequence()."); log.trace(tempAEFMessage); } int retVal = -1; if ( password == null || password.length() == 0) { // Error, unable to lookup default password for terminal number. AEFException ex = new AEFException(AEFConst.CONFIG_ERROR, AEFConst.NO_DEFAULT_ID_CONFIGURED, "GSALogonActionImpl: Default ID and/or password not configured for terminal " + sessionID + ", unable to perform logon.\nSee applogon.properties for id/password configuration."); try { automationProvider.logoff(); } catch (AEFException e) { e.appendExceptions(ex); ex = e; } catch (RemoteException re) { // We should never get here because we are calling locally. tempAEFMessage.setMessage("There was a remote exception thrown in sendPasswordSequence of GSALogonActionImpl."); log.error(tempAEFMessage, re); } tempAEFMessage.setMessage("An AEF exception was thrown in GSALogonActionImpl.sendPasswordSequence()."); log.error(tempAEFMessage, ex); throw ex; } // We have a password so lets signon. args.clear(); args.put("%0", password); args.put("SEQUENCE_ID", "password"); keySequenceAction = (AEFAction)(actionFactory.makeAction(new ActionRequest("SimpleKeySequenceAction", args))); // Re-use the lock from the ID command if there, otherwise create a new one. if (lock == null) { lock = new ConditionLock(); } if (log.isDebugEnabled()) { tempAEFMessage.setMessage("About to wait on the perform action for 'password'"); log.debug(tempAEFMessage); } if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "logon", ">>>Sending logon password key sequence to application."); } retVal= lock.performActionAndWait("wait-for-item-entry-state", keySequenceAction, GSANormalConditionsImpl.getInstance().getShortConditions(), BadConditionsImpl.getInstance().getBadConditions(), getTimeout()); if (retVal < 0) { AEFErrorHandler errorHandler = new AEFErrorHandler("Send Signon Password Sequence Error"); retVal = errorHandler.handleError(lock, keySequenceAction, GSANormalConditionsImpl.getInstance().getShortConditions(), BadConditionsImpl.getInstance().getBadConditions(), getTimeout(), retVal); if (retVal < 0) { tempAEFMessage.setMessage("An AEF exception was thrown in GSALogonActionImpl.sendPasswordSequence()."); log.error(tempAEFMessage, errorHandler.getAllExceptions()); throw errorHandler.getAllExceptions(); } } if (log.isDebugEnabled()) { tempAEFMessage.setMessage(" Condition returned was " + retVal); log.debug(tempAEFMessage); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSALogonActionImpl.sendPasswordSequence()."); log.trace(tempAEFMessage); } } /** * Blocks the calling thread until a new operator object is created. * * * @return Object The Operator instance. * @exception AEFException */ private Operator waitForOperator() throws AEFException { if (log.isTraceEnabled()) { tempAEFMessage.setMessage("+Enter GSALogonActionImpl.waitForOperator()."); log.trace(tempAEFMessage); } Operator retVal = null; // Successfully got to transaction selection so wait for the operator object to be created. ObjectDetectorLock objLock = new ObjectDetectorLock(); retVal = (Operator)(objLock.waitForNewObject("wait-for-operator", detector, instanceNumber, getTimeout())); if (perfTrace.isEnabled(AEFPerfTrace. COARSE)) { perfTrace.reportTimer(AEFPerfTrace. COARSE, sessionID, "logon", "<<<Detected operator logon from application."); } if (log.isTraceEnabled()) { tempAEFMessage.setMessage("-Exit GSALogonActionImpl.waitForOperator()."); log.trace(tempAEFMessage); } return retVal; } /* Instance Variables */ protected AEFAction keySequenceAction; protected String id; protected String password; protected String newPassword; protected ConditionLock lock; protected ObjectDetector detector; protected int instanceNumber; }