/*
* 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:
*
AEFConst.CONFIG_ERROR, AEFConst.FACTORY_ERROR
*
Common Errors
*/
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:
*
AEFConst.INVALID_ARGUMENT, AEFConst.NEW_PASSWORD_PROHIBITED
*
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:
*
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:
*
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",
"<<