package pl.net.bluesoft.rnd.pt.ext.jbpm;
import static pl.net.bluesoft.util.lang.StringUtil.hasText;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.ProcessEngine;
import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.ProcessToolContextFactory;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolSessionFactory;
import pl.net.bluesoft.rnd.processtool.bpm.exception.ProcessToolException;
import pl.net.bluesoft.rnd.processtool.dao.ProcessDefinitionDAO;
import pl.net.bluesoft.rnd.processtool.dao.ProcessDictionaryDAO;
import pl.net.bluesoft.rnd.processtool.dao.ProcessInstanceDAO;
import pl.net.bluesoft.rnd.processtool.dao.ProcessInstanceFilterDAO;
import pl.net.bluesoft.rnd.processtool.dao.ProcessInstanceSimpleAttributeDAO;
import pl.net.bluesoft.rnd.processtool.dao.ProcessStateActionDAO;
import pl.net.bluesoft.rnd.processtool.dao.UserDataDAO;
import pl.net.bluesoft.rnd.processtool.dao.UserProcessQueueDAO;
import pl.net.bluesoft.rnd.processtool.dao.UserSubstitutionDAO;
import pl.net.bluesoft.rnd.processtool.dict.GlobalDictionaryProvider;
import pl.net.bluesoft.rnd.processtool.dict.ProcessDictionaryProvider;
import pl.net.bluesoft.rnd.processtool.dict.ProcessDictionaryRegistry;
import pl.net.bluesoft.rnd.processtool.hibernate.HibernateBean;
import pl.net.bluesoft.rnd.processtool.hibernate.HibernateTransactionCallback;
import pl.net.bluesoft.rnd.processtool.model.BpmVariable;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstance;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceAttribute;
import pl.net.bluesoft.rnd.processtool.model.UserData;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessToolAutowire;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessToolSequence;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessToolSetting;
import pl.net.bluesoft.rnd.processtool.plugins.ProcessToolRegistry;
import pl.net.bluesoft.rnd.processtool.userqueues.IUserProcessQueueManager;
import pl.net.bluesoft.util.eventbus.EventBusManager;
import pl.net.bluesoft.util.lang.Formats;
/**
* Context replacement for Spring library
*
* @author tlipski@bluesoft.net.pl
*/
public class ProcessToolContextImpl implements ProcessToolContext {
private Session hibernateSession;
private Transaction transaction;
private ProcessToolJbpmSessionFactory processToolJbpmSessionFactory;
private ProcessDictionaryRegistry processDictionaryRegistry;
private ProcessEngine processEngine;
private ProcessToolContextFactory factory;
private IUserProcessQueueManager userProcessQueueManager;
private Map<String, String> autowiringCache;
private Map<Class<? extends HibernateBean>, HibernateBean> daoCache = new HashMap<Class<? extends HibernateBean>, HibernateBean>();
private Boolean closed = false;
public ProcessToolContextImpl(Session hibernateSession,
ProcessToolContextFactory factory,
ProcessEngine processEngine) {
this.hibernateSession = hibernateSession;
this.factory = factory;
this.processEngine = processEngine;
this.autowiringCache = getRegistry().getCache(ProcessToolAutowire.class.getName());
this.userProcessQueueManager = new UserProcessQueueManager(hibernateSession, getUserProcessQueueDAO());
processEngine.setHibernateSession(hibernateSession);
transaction = hibernateSession.beginTransaction();
}
public void rollback() {
transaction.rollback();
}
public void commit() {
transaction.commit();
}
public synchronized void close() {
try {
processEngine.close();
} finally {
try {
commit();
} finally {
hibernateSession.close();
closed = true;
}
}
}
private synchronized void verifyContextOpen() {
if (closed) {
throw new ProcessToolException("Context already closed!");
}
}
public void init() {
}
public boolean isActive() {
return !closed;
}
@Override
public void addTransactionCallback(HibernateTransactionCallback callback) {
transaction.registerSynchronization(callback);
}
@Override
public ProcessDictionaryRegistry getProcessDictionaryRegistry() {
if (processDictionaryRegistry == null) {
processDictionaryRegistry = new ProcessDictionaryRegistry();
processDictionaryRegistry.addProcessDictionaryProvider("db", (ProcessDictionaryProvider) getProcessDictionaryDAO());
processDictionaryRegistry.addGlobalDictionaryProvider("db", (GlobalDictionaryProvider) getProcessDictionaryDAO());
}
return processDictionaryRegistry;
}
@Override
public ProcessToolRegistry getRegistry() {
return factory.getRegistry();
}
@SuppressWarnings("unchecked")
private <T extends HibernateBean> T getHibernateDAO(Class<T> daoClass) {
verifyContextOpen();
if (!daoCache.containsKey(daoClass)) {
T dao = null;
if (ProcessDictionaryDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessDictionaryDAO(hibernateSession);
} else if (ProcessInstanceDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessInstanceDAO(hibernateSession);
} else if (ProcessInstanceFilterDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessInstanceFilterDAO(hibernateSession);
} else if (UserDataDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getUserDataDAO(hibernateSession);
} else if (ProcessDefinitionDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessDefinitionDAO(hibernateSession);
} else if (UserProcessQueueDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getUserProcessQueueDAO(hibernateSession);
} else if (UserSubstitutionDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getUserSubstitutionDAO(hibernateSession);
}else if (ProcessInstanceSimpleAttributeDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessInstanceSimpleAttributeDAO(hibernateSession);
}else if (ProcessStateActionDAO.class.equals(daoClass)) {
dao = (T) getRegistry().getProcessStateAction(hibernateSession);
}
if (dao != null) {
daoCache.put(daoClass, dao);
}
}
return (T) daoCache.get(daoClass);
}
public ProcessDictionaryDAO getProcessDictionaryDAO() {
return getHibernateDAO(ProcessDictionaryDAO.class);
}
@Override
public ProcessInstanceDAO getProcessInstanceDAO() {
return getHibernateDAO(ProcessInstanceDAO.class);
}
@Override
public ProcessInstanceFilterDAO getProcessInstanceFilterDAO() {
return getHibernateDAO(ProcessInstanceFilterDAO.class);
}
@Override
public UserDataDAO getUserDataDAO() {
return getHibernateDAO(UserDataDAO.class);
}
@Override
public ProcessDefinitionDAO getProcessDefinitionDAO() {
return getHibernateDAO(ProcessDefinitionDAO.class);
}
@Override
public UserSubstitutionDAO getUserSubstitutionDAO() {
return getHibernateDAO(UserSubstitutionDAO.class);
}
@Override
public UserProcessQueueDAO getUserProcessQueueDAO() {
return getHibernateDAO(UserProcessQueueDAO.class);
}
@Override
public ProcessInstanceSimpleAttributeDAO getProcessInstanceSimpleAttributeDAO() {
return getHibernateDAO(ProcessInstanceSimpleAttributeDAO.class);
}
@Override
public ProcessStateActionDAO getProcessStateActionDAO() {
return getHibernateDAO(ProcessStateActionDAO.class);
}
@Override
public Session getHibernateSession() {
verifyContextOpen();
return hibernateSession;
}
@Override
public synchronized ProcessToolSessionFactory getProcessToolSessionFactory() {
if (processToolJbpmSessionFactory == null) {
processToolJbpmSessionFactory = new ProcessToolJbpmSessionFactory(this);
}
return processToolJbpmSessionFactory;
}
@Override
public EventBusManager getEventBusManager() {
return factory.getRegistry().getEventBusManager();
}
@Override
public String getSetting(String key) {
verifyContextOpen();
ProcessToolSetting setting = (ProcessToolSetting) hibernateSession.createCriteria(ProcessToolSetting.class)
.add(Restrictions.eq("key", key)).uniqueResult();
return setting != null ? setting.getValue() : null;
}
@Override
public void setSetting(String key, String value) {
verifyContextOpen();
List list = hibernateSession.createCriteria(ProcessToolSetting.class).add(Restrictions.eq("key", key)).list();
ProcessToolSetting setting;
if (list.isEmpty()) {
setting = new ProcessToolSetting();
setting.setKey(key);
} else {
setting = (ProcessToolSetting) list.get(0);
}
setting.setValue(value);
hibernateSession.saveOrUpdate(setting);
}
@Override
public String getAutowiredProperty(String key) {
return autowiringCache.get(key);
}
@Override
public void setAutowiredProperty(String key, String value) {
String cachedValue = autowiringCache.get(key);
if (cachedValue == null || !cachedValue.equals(value)) {
verifyContextOpen();
ProcessToolAutowire pta = (ProcessToolAutowire) hibernateSession.createCriteria(ProcessToolAutowire.class)
.add(Restrictions.eq("key", key)).uniqueResult();
if (pta == null) {
pta = new ProcessToolAutowire();
pta.setKey(key);
}
pta.setValue(value);
hibernateSession.saveOrUpdate(pta);
autowiringCache.put(key, value);
}
}
@Override
public long getNextValue(String processDefinitionName, String sequenceName) {
verifyContextOpen();
List<ProcessToolSequence> seqList = hibernateSession.createCriteria(ProcessToolSequence.class)
.add(Restrictions.eq("processDefinitionName", processDefinitionName))
.add(Restrictions.eq("name", sequenceName))
.list();
ProcessToolSequence seq;
if (seqList.isEmpty()) {
seq = new ProcessToolSequence();
seq.setProcessDefinitionName(processDefinitionName);
seq.setName(sequenceName);
seq.setValue(1);
} else {
seq = seqList.get(0);
seq.setValue(seq.getValue() + 1);
}
hibernateSession.saveOrUpdate(seq);
hibernateSession.flush();
return seq.getValue();
}
@Override
public long getNextValue(ProcessInstance processInstance, String sequenceName) {
return getNextValue(processInstance.getDefinitionName(), sequenceName);
}
@Override
public long getNextValue(String sequenceName) {
return getNextValue((String) null, sequenceName);
}
@Override
public UserData getAutoUser() {
return new UserData(Formats.nvl(getSetting(AUTO_USER_LOGIN), "system"), Formats.nvl(getSetting(AUTO_USER_NAME), "System"),
Formats.nvl(getSetting(AUTO_USER_EMAIL), "awf@bluesoft.net.pl"));
}
public ProcessToolContextFactory getFactory() {
return factory;
}
public ProcessEngine getProcessEngine() {
return processEngine;
}
@Override
public void updateContext(ProcessInstance processInstance) {
ExecutionService es = getProcessEngine().getExecutionService();
for (ProcessInstanceAttribute pia : processInstance.getProcessAttributes()) {
if (pia instanceof BpmVariable) {
BpmVariable bpmVar = (BpmVariable) pia;
if (hasText(bpmVar.getBpmVariableName())) {
es.setVariable(processInstance.getInternalId(), bpmVar.getBpmVariableName(), bpmVar.getBpmVariableValue());
}
}
}
}
public Map<String, Object> getBpmVariables(ProcessInstance pi) {
ExecutionService es = getProcessEngine().getExecutionService();
return es.getVariables(pi.getInternalId(), es.getVariableNames(pi.getInternalId()));
}
public Object getBpmVariable(ProcessInstance pi, String variableName) {
ExecutionService es = getProcessEngine().getExecutionService();
return es.getVariable(pi.getInternalId(), variableName);
}
@Override
public IUserProcessQueueManager getUserProcessQueueManager()
{
return userProcessQueueManager;
}
}