package is.idega.idegaweb.egov.bpm.cases.exe;
import is.idega.idegaweb.egov.bpm.cases.actionhandlers.CaseHandlerAssignmentHandler;
import is.idega.idegaweb.egov.cases.business.CasesBusiness;
import is.idega.idegaweb.egov.cases.data.GeneralCase;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.annotation.Resource;
import javax.ejb.FinderException;
import org.jbpm.JbpmContext;
import org.jbpm.JbpmException;
import org.jbpm.graph.def.Event;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.idega.block.process.business.CaseBusiness;
import com.idega.block.process.business.ProcessConstants;
import com.idega.block.process.data.Case;
import com.idega.bpm.exe.DefaultBPMProcessInstanceW;
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.JbpmCallback;
import com.idega.jbpm.events.VariableCreatedEvent;
import com.idega.jbpm.exe.ProcessManager;
import com.idega.jbpm.exe.ProcessWatch;
import com.idega.jbpm.exe.ProcessWatchType;
import com.idega.presentation.IWContext;
import com.idega.user.data.User;
import com.idega.util.ListUtil;
import com.idega.util.expression.ELUtil;
/**
* @author <a href="mailto:civilis@idega.com">Vytautas Čivilis</a>
* @version $Revision: 1.23 $
*
* Last modified: $Date: 2009/02/06 19:00:40 $ by $Author: civilis $
*/
@Scope("prototype")
@Service("casesPIW")
public class CasesBPMProcessInstanceW extends DefaultBPMProcessInstanceW {
@Autowired
private CasesBPMDAO casesBPMDAO;
@Autowired
@ProcessWatchType("cases")
private ProcessWatch processWatcher;
@Override
@Required
@Resource(name = "casesBpmProcessManager")
public void setProcessManager(ProcessManager processManager) {
super.setProcessManager(processManager);
}
@Override
@Transactional(readOnly = false)
public void assignHandler(final Integer handlerUserId) {
getBpmContext().execute(new JbpmCallback() {
@Override
public Object doInJbpm(JbpmContext context) throws JbpmException {
ProcessInstance pi = getProcessInstance();
// creating new token, so there are no race conditions for
// variables
Token tkn = new Token(pi.getRootToken(), "assignUnassignHandler_" + System.currentTimeMillis());
ExecutionContext ectx = new ExecutionContext(tkn);
IWContext iwc = IWContext.getCurrentInstance();
Integer performerId = iwc.getCurrentUserId();
ectx.setVariable(CaseHandlerAssignmentHandler.performerUserIdVarName, performerId);
Map<String, Object> createdVars = new HashMap<String, Object>();
createdVars.put(CaseHandlerAssignmentHandler.performerUserIdVarName, performerId);
if (handlerUserId != null) {
ectx.setVariable(CaseHandlerAssignmentHandler.handlerUserIdVarName, handlerUserId);
createdVars.put(CaseHandlerAssignmentHandler.handlerUserIdVarName, handlerUserId);
}
VariableCreatedEvent performerVarCreated = new VariableCreatedEvent(
this,
pi.getProcessDefinition().getName(),
pi.getId(),
null,
createdVars
);
ELUtil.getInstance().publishEvent(performerVarCreated);
String event = null;
if (handlerUserId != null) {
event = CaseHandlerAssignmentHandler.assignHandlerEventType;
} else {
event = CaseHandlerAssignmentHandler.unassignHandlerEventType;
}
// Firing event to process...
pi.getProcessDefinition().fireEvent(event, ectx);
// And to it's subprocesses...
List<ProcessInstance> subProcesses = getBpmDAO().getSubprocessInstancesOneLevel(pi.getId());
for (ProcessInstance subProcessInstance: subProcesses) {
subProcessInstance.getProcessDefinition().fireEvent(event, ectx);
}
return null;
}
});
}
private IWApplicationContext getIWAC() {
final IWContext iwc = IWContext.getCurrentInstance();
final IWApplicationContext iwac;
// trying to get iwma from iwc, if available, downgrading to default
// iwma, if not
if (iwc != null) {
iwac = iwc;
} else {
iwac = IWMainApplication.getDefaultIWApplicationContext();
}
return iwac;
}
protected CasesBusiness getCasesBusiness(IWApplicationContext iwac) {
try {
return IBOLookup.getServiceInstance(iwac,
CasesBusiness.class);
} catch (IBOLookupException ile) {
throw new IBORuntimeException(ile);
}
}
@Override
@Transactional(readOnly = true)
public String getProcessDescription() {
String description = (String) getProcessInstance().getContextInstance()
.getVariable(ProcessConstants.CASE_DESCRIPTION);
return description;
}
@Override
public String getProcessOwner() {
Long piId = null;
try {
piId = getProcessInstanceId();
CaseProcInstBind bind = getCasesBPMDAO().getCaseProcInstBindByProcessInstanceId(piId);
if (bind == null) {
return null;
}
CaseBusiness caseBusiness = getServiceInstance(CaseBusiness.class);
Case theCase = caseBusiness.getCase(bind.getCaseId());
User owner = theCase == null ? null : theCase.getOwner();
return owner == null ? null : owner.getName();
} catch (Exception e) {
getLogger().log(Level.WARNING, "Error resolving process (ID: " + piId + ") owner", e);
}
return null;
}
@Override
@Transactional(readOnly = true)
public String getProcessIdentifier() {
return (String) getProcessInstance().getContextInstance().getVariable(
ProcessConstants.CASE_IDENTIFIER);
}
@Override
@Transactional(readOnly = true)
public Integer getHandlerId() {
CaseProcInstBind cpi = getCasesBPMDAO().find(CaseProcInstBind.class,
getProcessInstanceId());
Integer caseId = cpi.getCaseId();
try {
IWApplicationContext iwac = getIWAC();
CasesBusiness casesBusiness = getCasesBusiness(iwac);
GeneralCase genCase = casesBusiness.getGeneralCase(caseId);
User currentHandler = genCase.getHandledBy();
return currentHandler == null ? null : new Integer(currentHandler
.getPrimaryKey().toString());
} catch (RemoteException e) {
throw new IBORuntimeException(e);
} catch (FinderException e) {
throw new IBORuntimeException(e);
}
}
@Override
@Transactional(readOnly = true)
public boolean hasHandlerAssignmentSupport() {
Boolean res = getBpmContext().execute(new JbpmCallback() {
@Override
@SuppressWarnings("unchecked")
public Object doInJbpm(JbpmContext context) throws JbpmException {
Map<String, Event> events = getProcessInstance()
.getProcessDefinition().getEvents();
boolean result = events != null
&& events.containsKey(CaseHandlerAssignmentHandler.assignHandlerEventType);
if (result == Boolean.FALSE) {
List<ProcessInstance> subprocesses = getBpmDAO().getSubprocessInstancesOneLevel(getProcessInstance().getId());
if (ListUtil.isEmpty(subprocesses)) {
return Boolean.FALSE;
}
for (ProcessInstance pi : subprocesses) {
events = pi.getProcessDefinition().getEvents();
if (events != null && events.containsKey(CaseHandlerAssignmentHandler.assignHandlerEventType)) {
return Boolean.TRUE;
}
}
}
return result;
}
});
return res;
}
public CasesBPMDAO getCasesBPMDAO() {
return casesBPMDAO;
}
@Override
public ProcessWatch getProcessWatcher() {
return processWatcher;
}
}