package is.idega.idegaweb.egov.bpm.cases.actionhandlers; import is.idega.idegaweb.egov.bpm.cases.CasesStatusMapperHandler; import is.idega.idegaweb.egov.cases.business.CasesBusiness; import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import com.idega.block.process.data.Case; import com.idega.block.process.data.CaseHome; import com.idega.business.IBOLookup; import com.idega.business.IBOLookupException; import com.idega.business.IBORuntimeException; import com.idega.core.business.DefaultSpringBean; import com.idega.data.IDOLookup; import com.idega.data.IDOLookupException; import com.idega.idegaweb.IWApplicationContext; import com.idega.idegaweb.IWMainApplication; import com.idega.idegaweb.egov.bpm.data.CaseProcInstBind; import com.idega.idegaweb.egov.bpm.data.dao.CasesBPMDAO; import com.idega.jbpm.exe.BPMFactory; import com.idega.jbpm.exe.ProcessInstanceW; import com.idega.jbpm.process.business.messages.MessageValueContext; import com.idega.jbpm.process.business.messages.MessageValueHandler; import com.idega.presentation.IWContext; import com.idega.user.business.UserBusiness; import com.idega.user.data.User; import com.idega.util.CoreUtil; import com.idega.util.StringUtil; import com.idega.util.expression.ELUtil; /** * @author <a href="mailto:civilis@idega.com">Vytautas Čivilis</a> * @version $Revision: 1.8 $ Last modified: $Date: 2009/06/23 10:22:22 $ by $Author: valdas $ */ @Service("casesStatusHandler") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class CasesStatusHandler extends DefaultSpringBean implements ActionHandler { private static final long serialVersionUID = 7504445907540445936L; private static final Logger LOGGER = Logger.getLogger(CasesStatusHandler.class.getName()); @Autowired private MessageValueHandler messageValueHandler; private CaseHome caseHome = null; protected CaseHome getCaseHome() { if (caseHome == null) { try { caseHome = (CaseHome) IDOLookup.getHome(Case.class); } catch (IDOLookupException e) { getLogger().log(Level.WARNING, "Unable to get " + CaseHome.class, e); } } return caseHome; } /** * variable which contains string representation of case status to set */ private String caseStatus; private String caseStatusMappedName; private Map<String, String> commentExpression; private String commentValues; /** * if set, then it's checked, if the current status matches, and only then the status is changed * (for instance, if status specified by ifCaseStatusExp is received, then it may change to in * progress) */ private String ifCaseStatus; private String ifCaseStatusMappedName; /** * performer, if not set, current user is used */ private Integer performerUserId; /** * if set - is used. if no caseId or processInstanceId set explicitly, the mainProcessInstanceId * is used */ private Integer caseId; /** * used if set and caseId not set. if no caseId or processInstanceId set explicitly, the * mainProcessInstanceId is used */ private Long processInstanceId; @Autowired private CasesBPMDAO casesBPMDAO; @Autowired private BPMFactory bpmFactory; @Autowired private CasesStatusMapperHandler casesStatusMapperHandler; @Override public void execute(ExecutionContext ectx) throws Exception { String status = null; Integer caseId = null; try { caseId = getCaseId(ectx); if (caseId == null) { LOGGER.warning("No caseId resolved, skipping case status change"); return; } status = getCaseStatus(); Integer performerUserId = getPerformerUserId(); final String ifCaseStatus = getIfCaseStatus(); IWContext iwc = CoreUtil.getIWContext(); IWApplicationContext iwac = getIWAC(iwc); CasesBusiness casesBusiness = getCasesBusiness(iwac); final Case theCase = casesBusiness.getCase(caseId); if (status == null) status = theCase.getStatus(); if (ifCaseStatus == null || ifCaseStatus.equals(theCase.getCaseStatus().getStatus())) { // only changing if ifCaseStatus equals current case status, or ifCaseStatus not set (i.e. change always) User performer = null; if (performerUserId == null) { if (iwc != null) { if (iwc.isLoggedOn()) performer = iwc.getCurrentUser(); else performer = iwc.getAccessController().getAdministratorUser(); } else { LOGGER.warning("Cannot resolve current IWContext, so cannot resolve current user. Using no performer"); performer = null; } } else { performer = getUserBusiness(iwac).getUser(performerUserId); } try { if (performer == null) performer = getBpmFactory().getBpmUserFactory().getCurrentBPMUser().getUserToUse(); } catch(Exception e) {} String comment = getComment(ectx, getCurrentLocale(), performer); casesBusiness.changeCaseStatusDoNotSendUpdates(theCase, status, performer, comment, true); } } catch (Exception e) { String message = "Exception while changing case status to '" + status + "' for the case: " + caseId; LOGGER.log(Level.SEVERE, message, e); CoreUtil.sendExceptionNotification(message, e); } } public String getCaseStatus() { if (caseStatus == null) { if (!StringUtil.isEmpty(getCaseStatusMappedName())) { caseStatus = getCasesStatusMapperHandler().getStatusCodeByMappedName(getCaseStatusMappedName()); } } return caseStatus; } public String getIfCaseStatus() { if (ifCaseStatus == null) { if (!StringUtil.isEmpty(getIfCaseStatusMappedName())) { ifCaseStatus = getCasesStatusMapperHandler() .getStatusCodeByMappedName(getIfCaseStatusMappedName()); } } return ifCaseStatus; } private Integer getCaseId(ExecutionContext ectx) { if (caseId == null) { Long processInstanceIdToUse = getProcessInstanceId(ectx); CaseProcInstBind cpi = getCasesBPMDAO().getCaseProcInstBindByProcessInstanceId(processInstanceIdToUse); if (cpi == null) { LOGGER.warning("No case process instance bind found for process instance id=" + processInstanceIdToUse); return null; } caseId = cpi.getCaseId(); } return caseId; } /** * <p>Method for returning of instance id of jBPM process. Look at * /resources/processes/SomeProcess/processdefinition.xml for deeper * understanding or <a href=http://docs.jboss.org/jbpm>jBPM</a>.</p> * @param ectx org.jbpm.graph.exe.ExecutionContext. * @return id. */ protected Long getProcessInstanceId(ExecutionContext ectx) { Long processInstanceIdToUse; if (getProcessInstanceId() != null) { processInstanceIdToUse = getProcessInstanceId(); } else { Long currentProcessInstanceId = ectx.getProcessInstance().getId(); processInstanceIdToUse = getBpmFactory().getMainProcessInstance(currentProcessInstanceId).getId(); } return processInstanceIdToUse; } private IWApplicationContext getIWAC(IWContext iwc) { return iwc == null ? IWMainApplication.getDefaultIWApplicationContext() : iwc; } protected CasesBusiness getCasesBusiness(IWApplicationContext iwac) { try { return IBOLookup.getServiceInstance(iwac, CasesBusiness.class); } catch (IBOLookupException ile) { throw new IBORuntimeException(ile); } } protected UserBusiness getUserBusiness(IWApplicationContext iwac) { try { return IBOLookup.getServiceInstance(iwac, UserBusiness.class); } catch (IBOLookupException ile) { throw new IBORuntimeException(ile); } } public CasesBPMDAO getCasesBPMDAO() { return casesBPMDAO; } public void setCasesBPMDAO(CasesBPMDAO casesBPMDAO) { this.casesBPMDAO = casesBPMDAO; } public void setCaseStatus(String caseStatus) { this.caseStatus = caseStatus; } public void setIfCaseStatus(String ifCaseStatus) { this.ifCaseStatus = ifCaseStatus; } public Integer getPerformerUserId() { return performerUserId; } public void setPerformerUserId(Integer performerUserId) { this.performerUserId = performerUserId; } public Integer getCaseId() { return caseId; } public void setCaseId(Integer caseId) { this.caseId = caseId; } public Long getProcessInstanceId() { return processInstanceId; } public void setProcessInstanceId(Long processInstanceId) { this.processInstanceId = processInstanceId; } public String getCaseStatusMappedName() { return caseStatusMappedName; } public void setCaseStatusMappedName(String caseStatusMappedName) { this.caseStatusMappedName = caseStatusMappedName; } public String getIfCaseStatusMappedName() { return ifCaseStatusMappedName; } public void setIfCaseStatusMappedName(String ifCaseStatusMappedName) { this.ifCaseStatusMappedName = ifCaseStatusMappedName; } protected BPMFactory getBpmFactory() { return bpmFactory; } CasesStatusMapperHandler getCasesStatusMapperHandler() { return casesStatusMapperHandler; } private String getComment(ExecutionContext context, Locale locale, User user) { if (locale == null) { LOGGER.warning("Locale is unknown, unable to resolve comment"); return null; } Map<String, String> commentExpr = getCommentExpression(); if (commentExpr == null) return null; String comment = commentExpr.get(locale.toString()); if (StringUtil.isEmpty(comment)) return null; if (StringUtil.isEmpty(getCommentValues())) return comment; MessageValueContext messageContext = new MessageValueContext(); messageContext.setValue(MessageValueContext.userBean, user); Long pid = getProcessInstanceId(); ProcessInstanceW piw = getBpmFactory().getProcessManagerByProcessInstanceId(pid).getProcessInstance(pid); messageContext.setValue(MessageValueContext.piwBean, piw); comment = getMessageValueHandler().getFormattedMessage(comment, getCommentValues(), context.getToken(), messageContext); return comment; } public Map<String, String> getCommentExpression() { return commentExpression; } public void setCommentExpression(Map<String, String> commentExpression) { this.commentExpression = commentExpression; } public String getCommentValues() { return commentValues; } public void setCommentValues(String commentValues) { this.commentValues = commentValues; } MessageValueHandler getMessageValueHandler() { if (messageValueHandler == null) ELUtil.getInstance().autowire(this); return messageValueHandler; } }