package pl.net.bluesoft.rnd.processtool.dao.impl;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import pl.net.bluesoft.rnd.processtool.dao.ProcessDefinitionDAO;
import pl.net.bluesoft.rnd.processtool.hibernate.SimpleHibernateBean;
import pl.net.bluesoft.rnd.processtool.model.BpmTask;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstance;
import pl.net.bluesoft.rnd.processtool.model.config.*;
import pl.net.bluesoft.util.lang.Lang;
import java.util.*;
import java.util.logging.Logger;
import static pl.net.bluesoft.util.lang.FormatUtil.nvl;
/**
* @author tlipski@bluesoft.net.pl
*/
public class ProcessDefinitionDAOImpl extends SimpleHibernateBean<ProcessDefinitionConfig>
implements ProcessDefinitionDAO {
private Logger logger = Logger.getLogger(ProcessDefinitionDAOImpl.class.getName());
public ProcessDefinitionDAOImpl(Session session) {
super(session);
}
public Collection<ProcessDefinitionConfig> getAllConfigurations() {
return getSession().createCriteria(ProcessDefinitionConfig.class).addOrder(Order.desc("processName")).list();
}
public Collection<ProcessDefinitionConfig> getActiveConfigurations() {
long start = System.currentTimeMillis();
List list = getSession().createCriteria(ProcessDefinitionConfig.class).addOrder(Order.desc("processName"))
.add(Restrictions.eq("latest", Boolean.TRUE))
.add(Restrictions.or(Restrictions.eq("enabled", Boolean.TRUE), Restrictions.isNull("enabled")))
.list();
long duration = System.currentTimeMillis() - start;
logger.severe("getActiveConfigurations: " + duration);
return list;
}
@Override
public ProcessDefinitionConfig getActiveConfigurationByKey(String key) {
return (ProcessDefinitionConfig) getSession().createCriteria(ProcessDefinitionConfig.class)
.add(Restrictions.eq("latest", Boolean.TRUE))
.add(Restrictions.eq("bpmDefinitionKey", key)).uniqueResult();
}
@Override
public Collection<ProcessQueueConfig> getQueueConfigs() {
return getSession().createCriteria(ProcessQueueConfig.class).list();
}
public ProcessStateConfiguration getProcessStateConfiguration(BpmTask task) {
// HibernateTemplate ht = getHibernateTemplate();
List res = getSession().createCriteria(ProcessStateConfiguration.class)
.add(Restrictions.eq("definition", task.getProcessInstance().getDefinition()))
.add(Restrictions.eq("name", task.getTaskName())).list();
if (res.isEmpty())
return null;
return (ProcessStateConfiguration) res.get(0);
}
@Override
public void updateOrCreateProcessDefinitionConfig(ProcessDefinitionConfig cfg) {
cfg.setCreateDate(new Date());
cfg.setLatest(true);
Set<ProcessStateConfiguration> stateConfigurations = cfg.getStates();
for (ProcessStateConfiguration state : stateConfigurations) {
state.setDefinition(cfg);
Set<ProcessStateAction> actions = state.getActions();
for (ProcessStateAction action : actions) {
action.setConfig(state);
for (ProcessStateActionPermission p : action.getPermissions()) {
p.setAction(action);
}
}
cleanupWidgetsTree(state.getWidgets(), null, new HashSet<ProcessStateWidget>());
}
for (ProcessDefinitionPermission permission : cfg.getPermissions()) {
permission.setDefinition(cfg);
}
Session session = getSession();
List<ProcessDefinitionConfig> lst = session.createCriteria(ProcessDefinitionConfig.class)
.add(Restrictions.eq("latest", true))
.add(Restrictions.eq("bpmDefinitionKey", cfg.getBpmDefinitionKey())).list();
for (ProcessDefinitionConfig c : lst) {
//porównujemy z nową konfiguracją - jeśli nic się nie zmienia, nie wgrywamy wersji
if (compareDefinitions(cfg,c) && compareDefinitions(c,cfg)) {
logger.warning("New process definition config is the same as: " + c.getId() + ", therefore skipping DB update");
return;
}
c.setLatest(false);
session.saveOrUpdate(c);
}
session.saveOrUpdate(cfg);
}
private boolean compareDefinitions(ProcessDefinitionConfig cfg, ProcessDefinitionConfig c) {
if (!cfg.getBpmDefinitionKey().equals(c.getBpmDefinitionKey())) return false;
if (!cfg.getDescription().equals(c.getDescription())) return false;
if (!cfg.getProcessName().equals(c.getProcessName())) return false;
if (!Lang.equals(cfg.getComment(), c.getComment()) ||
!Lang.equals(cfg.getTaskItemClass(), c.getTaskItemClass())) return false;
if (cfg.getStates().size() != c.getStates().size()) return false;
if (!Arrays.equals(cfg.getProcessLogo(), c.getProcessLogo())) return false;
Map<String,ProcessStateConfiguration> oldMap = new HashMap();
for (ProcessStateConfiguration s : cfg.getStates()) {
oldMap.put(s.getName(), s);
}
Map<String,ProcessStateConfiguration> newMap = new HashMap();
for (ProcessStateConfiguration s : c.getStates()) {
if (!oldMap.containsKey(s.getName())) return false;
newMap.put(s.getName(), s);
}
for (Map.Entry<String, ProcessStateConfiguration> entry : oldMap.entrySet()) {
String name = entry.getKey();
if (!newMap.containsKey(name)) return false;
if (!compareStates(entry.getValue(), newMap.get(name))) return false;
}
if (!comparePermissions(cfg.getPermissions(), c.getPermissions())) return false;
return true;
}
private boolean stringEq(String s1, String s2) {
return s1 == null && s2 == null || !(s1 != null && s2 == null) && !(s2 != null && s1 == null) && s1.equals(s2);
}
private boolean compareStates(ProcessStateConfiguration newState, ProcessStateConfiguration oldState) {
if (newState.getActions().size() != oldState.getActions().size()) return false;
if (!stringEq(newState.getDescription(),oldState.getDescription())) return false;
if (!stringEq(newState.getCommentary(),oldState.getCommentary())) return false;
if (!stringEq(newState.getCommentary(),oldState.getCommentary())) return false;
Map<String,ProcessStateAction> newActionMap = new HashMap();
for (ProcessStateAction a : newState.getActions()) {
newActionMap.put(a.getBpmName(), a);
}
for (ProcessStateAction a : oldState.getActions()) {
String name = a.getBpmName();
if (!newActionMap.containsKey(name)) return false;
if (!compareActions(newActionMap.get(name), a)) return false;
}
Set<ProcessStateWidget> newWidgets = newState.getWidgets();
Set<ProcessStateWidget> oldWidgets = oldState.getWidgets();
if (!comparePermissions(oldState.getPermissions(), newState.getPermissions())) return false;
return compareWidgets(newWidgets, oldWidgets);
}
private boolean compareWidgets(Set<ProcessStateWidget> newWidgets, Set<ProcessStateWidget> oldWidgets) {
if (newWidgets.size() != oldWidgets.size()) return false;
Map<String,ProcessStateWidget> widgetMap = new HashMap();
for (ProcessStateWidget w : newWidgets) {
widgetMap.put(w.getName()+w.getPriority(), w);
}
for (ProcessStateWidget w : oldWidgets) {
if (!widgetMap.containsKey(w.getName()+w.getPriority())) return false;
if (!compareWidgets(widgetMap.get(w.getName()+w.getPriority()), w)) return false;
}
return true;
}
private boolean compareWidgets(ProcessStateWidget newWidget, ProcessStateWidget oldWidget) {
if (newWidget.getAttributes().size() != oldWidget.getAttributes().size()) return false;
if (newWidget.getChildren().size() != oldWidget.getChildren().size()) return false;
Map<String,String> attrVals = new HashMap();
for (ProcessStateWidgetAttribute a : newWidget.getAttributes()) {
attrVals.put(a.getName(), a.getValue());
}
for (ProcessStateWidgetAttribute a : oldWidget.getAttributes()) {
if (!attrVals.containsKey(a.getName()) || !attrVals.get(a.getName()).equals(a.getValue())) return false;
}
return comparePermissions(newWidget.getPermissions(), oldWidget.getPermissions()) &&
compareWidgets(newWidget.getChildren(), oldWidget.getChildren());
}
private boolean compareActions(ProcessStateAction newAction, ProcessStateAction oldAction) {
return
nvl(newAction.getDescription(),"").equals(nvl(oldAction.getDescription(), "")) &&
nvl(newAction.getButtonName(),"").equals(nvl(oldAction.getButtonName(), "")) &&
nvl(newAction.getBpmName(),"").equals(nvl(oldAction.getBpmName(), "")) &&
nvl(newAction.getAutohide(),false).equals(nvl(oldAction.getAutohide(),false)) &&
nvl(newAction.getSkipSaving(),false).equals(nvl(oldAction.getSkipSaving(),false)) &&
nvl(newAction.getLabel(),"").equals(nvl(oldAction.getLabel(), "")) &&
nvl(newAction.getNotification(),"").equals(nvl(oldAction.getNotification(), "")) &&
Lang.equals(newAction.getMarkProcessImportant(), oldAction.getMarkProcessImportant()) &&
nvl(newAction.getPriority(),0).equals(nvl(oldAction.getPriority(), 0)) &&
compareAttributes(newAction.getAttributes(), oldAction.getAttributes()) &&
comparePermissions(newAction.getPermissions(), oldAction.getPermissions());
}
private boolean compareAttributes(Set<ProcessStateActionAttribute> attributes, Set<ProcessStateActionAttribute> attributes1) {
Map<String,String> attrVals = new HashMap();
for (ProcessStateActionAttribute a : attributes) {
attrVals.put(a.getName(), a.getValue());
}
for (ProcessStateActionAttribute a : attributes1) {
if (!attrVals.containsKey(a.getName()) || !attrVals.get(a.getName()).equals(a.getValue())) return false;
}
return true;
}
private boolean comparePermissions(Set<? extends AbstractPermission> newPermissions, Set<? extends AbstractPermission> oldPermissions) {
if (newPermissions.size() != oldPermissions.size()) return false;
Set<String> permissionSet = new HashSet();
for (AbstractPermission p : newPermissions) {
permissionSet.add(p.getPrivilegeName() + "|||" + p.getRoleName());
}
for (AbstractPermission p : oldPermissions) {
if (!permissionSet.contains(p.getPrivilegeName() + "|||" + p.getRoleName())) return false;
}
return true;
}
private void cleanupWidgetsTree(Set<ProcessStateWidget> widgets, ProcessStateWidget parent,
Set<ProcessStateWidget> processed) {
if (widgets != null) for (ProcessStateWidget stateWidget : widgets) {
if (processed.contains(stateWidget)) {
throw new RuntimeException("Error for config, recursive process state widget tree!");
}
if (stateWidget.getPermissions() != null) for (ProcessStateWidgetPermission p : stateWidget.getPermissions()) {
p.setWidget(stateWidget);
}
if (stateWidget.getAttributes() != null) for (ProcessStateWidgetAttribute a : stateWidget.getAttributes()) {
a.setWidget(stateWidget);
}
stateWidget.setParent(parent);
processed.add(stateWidget);
cleanupWidgetsTree(stateWidget.getChildren(), stateWidget, processed);
}
}
@Override
public void updateOrCreateQueueConfigs(Collection<ProcessQueueConfig> cfgs) {
Session session = getSession();
for (ProcessQueueConfig q : cfgs) {
List queues = session.createCriteria(ProcessQueueConfig.class)
.add(Restrictions.eq("name", q.getName())).list();
for (Object o :queues) {
session.delete(o);
}
for (ProcessQueueRight r : q.getRights()) {
r.setQueue(q);
}
//session.merge(q);
session.save(q);
}
}
@Override
public void removeQueueConfigs(Collection<ProcessQueueConfig> cfgs) {
Session session = getSession();
for (ProcessQueueConfig q : cfgs) {
List queues = session.createCriteria(ProcessQueueConfig.class)
.add(Restrictions.eq("name", q.getName())).list();
for (Object o : queues) {
session.delete(o);
}
}
}
@Override
public Collection<ProcessDefinitionConfig> getConfigurationVersions(ProcessDefinitionConfig cfg) {
return session.createCriteria(ProcessDefinitionConfig.class)
.add(Restrictions.eq("bpmDefinitionKey", cfg.getBpmDefinitionKey()))
.list();
}
@Override
public void setConfigurationEnabled(ProcessDefinitionConfig cfg, boolean enabled) {
cfg = (ProcessDefinitionConfig) session.get(ProcessDefinitionConfig.class, cfg.getId());
cfg.setEnabled(enabled);
session.save(cfg);
}
}