package is.idega.idegaweb.egov.bpm.cases.actionhandlers; import is.idega.idegaweb.egov.bpm.cases.messages.SendCaseMessagesHandler; import is.idega.idegaweb.egov.cases.business.CasesBusiness; import is.idega.idegaweb.egov.cases.data.GeneralCase; import java.rmi.RemoteException; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.logging.Logger; import javax.ejb.FinderException; import org.jbpm.graph.def.ActionHandler; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.exe.ProcessInstance; 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.business.ProcessConstants; import com.idega.business.IBOLookup; import com.idega.business.IBOLookupException; import com.idega.business.IBORuntimeException; 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.data.NativeIdentityBind.IdentityType; import com.idega.jbpm.exe.BPMFactory; import com.idega.jbpm.exe.ProcessWatch; import com.idega.jbpm.exe.ProcessWatchType; import com.idega.jbpm.identity.Identity; import com.idega.jbpm.identity.JSONExpHandler; import com.idega.jbpm.identity.Role; import com.idega.presentation.IWContext; import com.idega.user.business.UserBusiness; import com.idega.user.data.User; /** * @author <a href="mailto:civilis@idega.com">Vytautas Čivilis</a> * @version $Revision: 1.8 $ Last modified: $Date: 2009/02/23 12:40:24 $ by $Author: civilis $ */ @Service("caseHandlerAssignmentHandler") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class CaseHandlerAssignmentHandler implements ActionHandler { private static final long serialVersionUID = -6642593190563557536L; private String caseHandlerRoleExp; private String subjectKey; private String subjectValues; private String messageKey; private String messageValues; private String messagesBundle; private String sendToRoles; private Map<String, String> inlineSubject; private Map<String, String> inlineMessage; @Autowired private CasesBPMDAO casesBPMDAO; @Autowired @ProcessWatchType("cases") private ProcessWatch processWatcher; @Autowired private BPMFactory bpmFactory; @Autowired private SendCaseMessagesHandler sendCaseMessagesHandler; private Integer handlerUserId; private Integer recipientId; private Integer performerUserId; public static final String assignHandlerEventType = "handlerAssignedToCase"; public static final String unassignHandlerEventType = "handlerUnassignedFromCase"; public static final String handlerUserIdVarName = ProcessConstants.HANDLER_IDENTIFIER; public static final String performerUserIdVarName = "performerUserId"; public static final String recipientUserIdVarName = "recipientUserId"; protected ProcessInstance getProcessInstance(ExecutionContext ectx) { return ectx.getProcessInstance(); } @Override public void execute(ExecutionContext ectx) throws Exception { ProcessInstance pi = getProcessInstance(ectx); Long processInstanceId = pi.getId(); CaseProcInstBind cpi = getCasesBPMDAO().find(CaseProcInstBind.class, processInstanceId); String event = ectx.getEvent().getEventType(); Integer caseId = cpi.getCaseId(); try { IWApplicationContext iwac = getIWAC(); CasesBusiness casesBusiness = getCasesBusiness(iwac); GeneralCase genCase = casesBusiness.getGeneralCase(caseId); final Role caseHandlerRole; if (getCaseHandlerRoleExp() != null) { caseHandlerRole = JSONExpHandler.resolveRoleFromJSONExpression(getCaseHandlerRoleExp(), ectx); } else { String defaultCaseHandlerRoleName = "bpm_caseHandler"; Logger.getLogger(getClass().getName()).info("No caseHandler role expression found, using default=" + defaultCaseHandlerRoleName); caseHandlerRole = new Role(defaultCaseHandlerRoleName); } if (assignHandlerEventType.equals(event) || "node-enter".equals(event)) { unassign(genCase, processInstanceId, casesBusiness, ectx, caseHandlerRole); assign(genCase, pi, casesBusiness, ectx, iwac, caseHandlerRole); } else if (unassignHandlerEventType.equals(event)) { unassign(genCase, processInstanceId, casesBusiness, ectx, caseHandlerRole); } else throw new IllegalArgumentException("Illegal event type provided=" + ectx.getEvent().getEventType()); sendMessages(ectx); } catch (RemoteException e) { throw new IBORuntimeException(e); } catch (FinderException e) { throw new IBORuntimeException(e); } } protected void unassign( GeneralCase genCase, Long processInstanceId, CasesBusiness casesBusiness, ExecutionContext ectx, Role caseHandlerRole ) throws Exception { User currentHandler = genCase.getHandledBy(); if (currentHandler != null) { getProcessWatcher().removeWatch(processInstanceId, new Integer(currentHandler.getPrimaryKey().toString())); getBpmFactory().getRolesManager().removeIdentitiesForRoles( Arrays.asList(new Role[] { caseHandlerRole }), new Identity(currentHandler.getPrimaryKey().toString(), IdentityType.USER), processInstanceId ); } casesBusiness.untakeCase(genCase); } protected Integer getHandlerUserId(ExecutionContext ectx) { if (handlerUserId == null) handlerUserId = (Integer) ectx.getVariable(handlerUserIdVarName); if (handlerUserId == null) throw new IllegalStateException("No handler user id set"); return handlerUserId; } protected Integer getPerformerUserId(ExecutionContext ectx) { if (performerUserId == null) performerUserId = (Integer) ectx.getVariable(performerUserIdVarName); if (performerUserId == null) performerUserId = new Integer(getCurrentUser().getPrimaryKey().toString()); return performerUserId; } protected Integer getRecipientUserId(ExecutionContext ectx) { if (recipientId == null) recipientId = (Integer) ectx.getVariable(recipientUserIdVarName); return recipientId; } protected User getCurrentUser() { return IWContext.getCurrentInstance().getCurrentUser(); } protected void assign( GeneralCase genCase, ProcessInstance pi, CasesBusiness casesBusiness, ExecutionContext ectx, IWApplicationContext iwac, Role caseHandlerRole ) throws Exception { final Integer handlerUserId = getHandlerUserId(ectx); final Integer performerUserId = getPerformerUserId(ectx); // assigning handler final User currentHandler = genCase.getHandledBy(); if (currentHandler == null || !String.valueOf(handlerUserId).equals(String.valueOf(currentHandler.getPrimaryKey()))) { final UserBusiness userBusiness = getUserBusiness(iwac); final IWContext iwc = IWContext.getCurrentInstance(); final User handler = userBusiness.getUser(handlerUserId); final User performer = userBusiness.getUser(performerUserId); // statistics and status change. also keeping handlerId there casesBusiness.takeCase(genCase, handler, iwc, performer, true, false); // the case now appears in handler's mycases list getProcessWatcher().assignWatch(pi.getId(), handlerUserId); } // creating case handler role and assigning handler user to this, so // that 'ordinary' users could see their contacts etc (they have the // permission to see caseHandler contacts) final List<Role> roles = Arrays.asList(new Role[] { caseHandlerRole }); getBpmFactory().getRolesManager().createProcessActors(roles, pi); getBpmFactory().getRolesManager().createIdentitiesForRoles(roles, new Identity(handlerUserId.toString(), IdentityType.USER), pi.getId()); } protected void sendMessages(ExecutionContext ectx) throws Exception { SendCaseMessagesHandler msgHan = getSendCaseMessagesHandler(); msgHan.setMessageKey(getMessageKey()); msgHan.setMessagesBundle(getMessagesBundle()); msgHan.setMessageValues(getMessageValues()); msgHan.setSendToRoles(getSendToRoles()); msgHan.setSubjectKey(getSubjectKey()); msgHan.setSubjectValues(getSubjectValues()); msgHan.setInlineSubject(getInlineSubject()); msgHan.setInlineMessage(getInlineMessage()); if (getRecipientUserId(ectx) != null) { msgHan.setRecipientUserID(getRecipientUserId(ectx)); } else if (getHandlerUserId(ectx) != null) { msgHan.setRecipientUserID(getHandlerUserId(ectx)); } msgHan.execute(ectx); } 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 String getSubjectKey() { return subjectKey; } public void setSubjectKey(String subjectKey) { this.subjectKey = subjectKey; } public String getSubjectValues() { return subjectValues; } public void setSubjectValues(String subjectValues) { this.subjectValues = subjectValues; } public String getMessageKey() { return messageKey; } public void setMessageKey(String messageKey) { this.messageKey = messageKey; } public String getMessageValues() { return messageValues; } public void setMessageValues(String messageValues) { this.messageValues = messageValues; } public String getMessagesBundle() { return messagesBundle; } public void setMessagesBundle(String messagesBundle) { this.messagesBundle = messagesBundle; } public String getSendToRoles() { return sendToRoles; } public void setSendToRoles(String sendToRoles) { this.sendToRoles = sendToRoles; } public CasesBPMDAO getCasesBPMDAO() { return casesBPMDAO; } public ProcessWatch getProcessWatcher() { return processWatcher; } protected IWApplicationContext getIWAC() { final IWContext iwc = IWContext.getCurrentInstance(); final IWApplicationContext iwac; if (iwc != null) { iwac = iwc; } else { iwac = IWMainApplication.getDefaultIWApplicationContext(); } return iwac; } public Map<String, String> getInlineSubject() { return inlineSubject; } public void setInlineSubject(Map<String, String> inlineSubject) { this.inlineSubject = inlineSubject; } public Map<String, String> getInlineMessage() { return inlineMessage; } public void setInlineMessage(Map<String, String> inlineMessage) { this.inlineMessage = inlineMessage; } public BPMFactory getBpmFactory() { return bpmFactory; } public void setBpmFactory(BPMFactory bpmFactory) { this.bpmFactory = bpmFactory; } public String getCaseHandlerRoleExp() { return caseHandlerRoleExp; } public void setCaseHandlerRoleExp(String caseHandlerRoleExp) { this.caseHandlerRoleExp = caseHandlerRoleExp; } SendCaseMessagesHandler getSendCaseMessagesHandler() { return sendCaseMessagesHandler; } public void setHandlerUserId(Integer handlerUserId) { this.handlerUserId = handlerUserId; } public void setPerformerUserId(Integer performerUserId) { this.performerUserId = performerUserId; } }