package com.ebworx.core.base.web.struts.controller;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import com.ebworx.core.base.metadata.ICoreConstants;
import com.ebworx.core.base.web.struts.controller.form.TransactionDirectorForm;
import com.ebworx.core.base.web.struts.controller.helper.IBaseActionConstant;
import com.ebworx.core.webcore.GatewayBean;
import com.ebworx.kernel.gateway.ejb.Gateway;
import com.ebworx.kernel.transactiondirector.metadata.TCB;
import com.ebworx.kernel.transactiondirector.metadata.TCBPool;
import com.ebworx.kernel.transactiondirector.metadata.TCBPoolException;
import com.ebworx.services.common.server.helper.ApplicationException;
import com.ebworx.services.common.server.helper.BusinessError;
import com.ebworx.services.common.server.helper.BusinessException;
import com.ebworx.services.common.server.helper.ErrorList;
import com.ebworx.services.common.server.helper.ExceptionDefinitionConstant;
import com.ebworx.services.common.server.utils.UUIDProvider;
import com.ebworx.services.vo.metadata.AbstractBaseValueObject;
/**
* @author xiongyan
*/
public abstract class TransactionDirector extends Action
{
private static Gateway gateway = null;
private TCB tcbObjct = null;
private static Logger logger = Logger.getLogger( TransactionDirector.class );
/**
* Overwrite struts's execute method.
*
* @param actionMapping
* Action mapping.
* @param actionForm
* Action form.
* @param request
* HTTP Servlet request.
* @param response
* HTTP Servlet response.
* @return Action forward.
* @throws Exception
* If exception is caught.
*/
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) throws Exception
{
try
{
if (logger.isDebugEnabled())
{
logger.debug( "Entering TD execute." );
logger.debug( request.getRequestURL().toString() + "?"+ request.getQueryString() );
}
ActionForward nextPage = validateAccess( actionMapping, request,response );
if (nextPage != null)
{
return nextPage;
}
// get TCB from pool and initialise phaseId,start time, end time
tcbObjct = getTCBFromPool();
// set TCB fields
setTCBFields( request, tcbObjct );
// judge the time
Date currentDatetime = new Date();
SimpleDateFormat format = new SimpleDateFormat( "hh:MM:ss" );
if (( currentDatetime.before( tcbObjct.serviceStartTime ) || currentDatetime.after( tcbObjct.serviceEndTime ) ) && tcbObjct.isNewTransaction)
throw new TransactionDirectorException(ExceptionDefinitionConstant.ERROR,"TD","TD","TD-001",
"can't create new transaction out range of time:"
+ format.format( tcbObjct.serviceStartTime )
+ "~"+ format.format( tcbObjct.serviceEndTime ) );
logger.debug( "time checked successfully" );
// call validateTcb
try
{
// tcbObjct = getGatewayEJB().fetchTCB( tcbObjct );
tcbObjct = getGatewayEJB().sessionCheck( tcbObjct );
}
catch(BusinessException e)
{
//User has been force out!
if (logger.isDebugEnabled())
{
logger.debug( "User has been force out!" );
}
ActionErrors errors = new ActionErrors();
errors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage(IBaseActionConstant.USER_FORCE_OUT));
//request.setAttribute(Globals.ERROR_KEY,errors);
addErrors( request, errors );
return actionMapping.findForward(IBaseActionConstant.FORCE_LOG_OUT);
}
// check action form type
tcbObjct.requestVOs = new ArrayList();
nextPage = processExecute( actionMapping,(TransactionDirectorForm)actionForm,request, response, tcbObjct );
if (nextPage != null)
{
return nextPage;
}
throw new TransactionDirectorException("Return-mapping is missing",null );
} catch ( BusinessException be )
{
logger.debug( "BusinessException be" );
be.printStackTrace();
handleBusinessException( request, be );
// return to entry page if business exception
return errorPageForward( actionMapping,(TransactionDirectorForm)actionForm,request, response, tcbObjct );
}
catch ( Exception e )
{
ActionMessages actionMessages = (ActionMessages) request.getAttribute(ActionErrors.GLOBAL_MESSAGE);
if (actionMessages == null)
{
saveErrors(request, new ActionMessages());
} else
{
actionMessages.clear();
}
if (e.getCause() instanceof ApplicationException)
{
ActionErrors errors = new ActionErrors();
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ICoreConstants.COMMON_ERROR_0006,( (ApplicationException)e.getCause() ).toErrorString() ) );
addErrors( request, errors );
return actionMapping.findForward( IBaseActionConstant.ERROR_PAGE );
}
if (e.getCause() instanceof BusinessException)
{
handleBusinessException( request, (BusinessException)e.getCause() );
return errorPageForward( actionMapping,(TransactionDirectorForm)actionForm,request, response, tcbObjct );
}
else
{
logger.error( "Runtime exception throw to base action.", e );
ActionErrors errors = new ActionErrors();
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(ICoreConstants.COMMON_ERROR_0006 ) );
addErrors( request, errors );
return actionMapping.findForward( IBaseActionConstant.ERROR_PAGE );
}
} finally
{
if (tcbObjct != null)
{
request.setAttribute( IBaseActionConstant.RESPONSE_TCB, tcbObjct );
releaseTCB( tcbObjct );
tcbObjct = null;
}
}
}
/**
* Common method to append messages to user session, so that jsp will
* display the message.
*
* @param messageResourceKey
* @param params
* @param request
*/
protected final void addActionMessage(String messageResourceKey, Object[] params, HttpServletRequest request)
{
ActionMessages actionMessages = (ActionMessages)request.getAttribute( ActionErrors.GLOBAL_MESSAGE );
if (actionMessages == null)
{
actionMessages = new ActionMessages();
}
if (params == null)
{
actionMessages.add( ActionErrors.GLOBAL_MESSAGE, new ActionMessage( messageResourceKey ) );
}
else
{
actionMessages.add( ActionErrors.GLOBAL_MESSAGE, new ActionMessage( messageResourceKey,params ) );
}
saveErrors( request, actionMessages );
}
/**
* Get current page no from listing.
*
* @param request
* @return
*/
public static int getCurrentPageNo(HttpServletRequest request)
{
return request.getParameter( "currentPage" ) == null ? 1 : Integer.parseInt( request.getParameter( "currentPage" ) );
}
/**
* Common method to append messages to user session, so that jsp will
* display the message. - without params. created by : alwin ling
*
* @param messageResourceKey
* @param request
*/
protected final void addActionMessage(String messageResourceKey, HttpServletRequest request)
{
addActionMessage( messageResourceKey, null, request );
}
/**
* Default error page forward back to origin "post" page. Will be overrided
* by module, module will decide where to route to when error.
*
* @param actionMapping
* @param baseActionForm
* @return
*/
protected ActionForward errorPageForward(ActionMapping actionMapping, TransactionDirectorForm form, HttpServletRequest request, HttpServletResponse response, TCB tcb)
{
return actionMapping.getInputForward();
}
/**
* Validate access via SecurityManager.
*
* @param actionMapping
* Action mapping.
* @param request
* HTTP Servlet request.
* @param response
* HTTP Servlet response.
* @return Action forward.
* @throws Exception
* If exception is caught.
*/
protected ActionForward validateAccess(ActionMapping actionMapping, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
ActionForward actionForward = null;
if ((request.getSession(false) == null) ||(request.getSession(false).isNew()))
{
if (logger.isDebugEnabled())
{
logger.debug( "Session time out." );
}
ActionErrors errors = new ActionErrors();
errors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage(IBaseActionConstant.SESSION_TIME_OUT));
addErrors( request, errors );
actionForward = actionMapping.findForward(IBaseActionConstant.FORCE_LOG_OUT);
}
return actionForward;
}
protected void validateToken(HttpServletRequest request) throws BusinessException
{
if (!isTokenValid( request, true ))
{
throw new BusinessException( "common.error.webMultipleSubmission", "Multiple add submission detected." );
}
}
/**
* invoke the module action's method by reflection
*
* @param actionMapping
* @param actionForm
* @param request
* @param response
* @param tcb
* @return
* @throws Exception
*/
protected ActionForward processExecute(ActionMapping actionMapping,
TransactionDirectorForm actionForm,
HttpServletRequest request,
HttpServletResponse response,
TCB tcb)
throws Exception
{
if (logger.isDebugEnabled())
{
logger.debug( "Base action processExecute:" + request.getParameter( "do" ) );
}
String forward = (String)this.getClass().getMethod(request.getParameter( "do" ),new Class[] {
TransactionDirectorForm.class,
HttpServletRequest.class,
HttpServletResponse.class,
TCB.class } ).invoke(this,new Object[] { actionForm,
request,response,tcbObjct } );
return actionMapping.findForward( forward );
}
/**
* release TCB object
*
* @param tcb
* @throws TCBPoolException
*/
protected void releaseTCB(TCB tcb) throws TCBPoolException
{
TCBPool.getInstance().release( tcb );
}
/**
* get TCB object from TCB pool
*
* @return
* @throws Exception
*/
private TCB getTCBFromPool() throws Exception
{
logger.debug( "getTCBFromPool" );
TCB tcb = TCBPool.getInstance().get( UUIDProvider.getUUID() );
return tcb;
}
/**
* invoke gatewayEJB
*
* @return
* @throws Exception
*/
private Gateway getGatewayEJB() throws Exception
{
if (gateway == null)
{
gateway = GatewayBean.getInstance().getGatewayEJB();
}
return gateway;
}
private void setTCBFields(HttpServletRequest request, TCB tcb)
{
tcb.sessionId = request.getSession().getId();
tcb.ipAddress = request.getRemoteAddr();
// tcb.isNewTransaction = true;
tcb.isLogPhasePrimeInformation = true;
}
/**
* Method to handle BusinessException
*
* @param request
* @param e
*/
private void handleBusinessException(HttpServletRequest request, BusinessException e)
{
if (logger.isDebugEnabled())
{
logger.debug( "Calling handleBusinessException" );
}
ErrorList errors = new ErrorList();
errors.addErrors( e.getErrorList() );
logger.debug( "Number Of Error/Warning : " + errors.getNumberOfErrors() );
if (errors.getNumberOfErrors() > 0)
logger.debug( "Exception=" + e );
if (errors.getNumberOfErrors() != 0)
for (int i = 0; i < errors.getErrorList().size(); i++)
{
BusinessError error = (BusinessError)errors.getErrorList()
.get( i );
ActionErrors actionErrors = new ActionErrors();
// @todo need further dicussion on error message bundling
// approach
actionErrors.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage(error.getErrorCode(), error.getSubstitutionValues() ) );
addErrors( request, actionErrors );
}
}
protected abstract TransactionDirectorForm VOS2Form(List vos, TransactionDirectorForm actionForm) throws BusinessException;
protected abstract AbstractBaseValueObject Form2VOS( TransactionDirectorForm actionForm, List vos) throws BusinessException;
}