Package pl.net.bluesoft.rnd.processtool.bpm.impl

Source Code of pl.net.bluesoft.rnd.processtool.bpm.impl.AbstractProcessToolSession

package pl.net.bluesoft.rnd.processtool.bpm.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import pl.net.bluesoft.rnd.processtool.ProcessToolContext;
import pl.net.bluesoft.rnd.processtool.bpm.BpmEvent;
import pl.net.bluesoft.rnd.processtool.bpm.BpmEvent.Type;
import pl.net.bluesoft.rnd.processtool.bpm.ProcessToolBpmSession;
import pl.net.bluesoft.rnd.processtool.event.IEvent;
import pl.net.bluesoft.rnd.processtool.event.ProcessToolEventBusManager;
import pl.net.bluesoft.rnd.processtool.hibernate.TransactionFinishedCallback;
import pl.net.bluesoft.rnd.processtool.model.BpmTask;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstance;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceLog;
import pl.net.bluesoft.rnd.processtool.model.ProcessInstanceSimpleAttribute;
import pl.net.bluesoft.rnd.processtool.model.ProcessStatus;
import pl.net.bluesoft.rnd.processtool.model.UserData;
import pl.net.bluesoft.rnd.processtool.model.config.AbstractPermission;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessDefinitionConfig;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessDefinitionPermission;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessQueueConfig;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessQueueRight;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessStateAction;
import pl.net.bluesoft.rnd.processtool.model.config.ProcessStateWidget;
import pl.net.bluesoft.rnd.processtool.model.nonpersistent.MutableBpmTask;
import pl.net.bluesoft.rnd.processtool.model.nonpersistent.ProcessQueue;
import pl.net.bluesoft.rnd.processtool.plugins.ProcessToolRegistry;
import pl.net.bluesoft.util.eventbus.EventBusManager;
import pl.net.bluesoft.util.lang.Collections;
import pl.net.bluesoft.util.lang.Mapcar;
import pl.net.bluesoft.util.lang.Pair;
import pl.net.bluesoft.util.lang.Predicate;

/**
* @author tlipski@bluesoft.net.pl
* @author mpawlak@bluesoft.net.pl
*/
public abstract class AbstractProcessToolSession
        implements ProcessToolBpmSession, Serializable {

    protected Logger log = Logger.getLogger(ProcessToolBpmSession.class.getName());

    /**
     * User and role names are provided externally, e.g. from Liferay.
     * Of course, the implementation can load the roleNames by itself.
     */
    protected UserData user;
    protected EventBusManager eventBusManager;
    protected Collection<String> roleNames;

    protected UserData substitutingUser;
    protected EventBusManager substitutingUserEventBusManager;

    public AbstractProcessToolSession(UserData user, Collection<String> roleNames, ProcessToolRegistry registry) {
        this.user = user;
        this.roleNames = new HashSet<String>(roleNames);
        this.eventBusManager = new ProcessToolEventBusManager(registry, registry.getExecutorService());
        log.finest("Created session for user: " + user);
    }
   
    /** Method creates new subprocess instance of given parent process. The creator of new process
     * is set to the parent process creator. The parent process list is updated with newly created
     * child process instance
     *
     */
    public ProcessInstance createSubprocessInstance(ProcessDefinitionConfig config, ProcessToolContext ctx,
      ProcessInstance parentProcessInstance, String source, String id)
    {

      ProcessInstance newSubprocessInstance = createProcessInstance(config, null, ctx, null, null, source, id, parentProcessInstance.getCreator());
     
      /* Corelate parent process with it's new child process */
      newSubprocessInstance.setParent(parentProcessInstance);   
      parentProcessInstance.getChildren().add(newSubprocessInstance);
     
     
      /* Map parent process owners to subprocess */
      newSubprocessInstance.getOwners().addAll(parentProcessInstance.getOwners());
     
      /* Inform about parent process halt */
        broadcastEvent(ctx, new BpmEvent(Type.PROCESS_HALTED, parentProcessInstance, parentProcessInstance.getCreator()));
     
      return newSubprocessInstance;
  }

  /**
   * Methods crates a new process instance and sets the creator to current
   * context user
   */
    public ProcessInstance createProcessInstance(ProcessDefinitionConfig config,String externalKey, ProcessToolContext ctx,
            String description, String keyword, String source, String internalId)
    {
      return createProcessInstance(config, externalKey, ctx, description, keyword, source, internalId, user);
    }

    public ProcessInstance createProcessInstance(ProcessDefinitionConfig config,
                                                 String externalKey,
                                                 ProcessToolContext ctx,
                                                 String description,
                                                 String keyword,
                                                 String source, String internalId, UserData creator) {
      long start = System.currentTimeMillis();
        if (!config.getEnabled()) {
            throw new IllegalArgumentException("Process definition has been disabled!");
        }
       
        ProcessInstance newProcessInstance = new ProcessInstance();
        newProcessInstance.setDefinition(config);
        newProcessInstance.setCreator(creator);
        newProcessInstance.addOwner(creator.getLogin());
        newProcessInstance.setDefinitionName(config.getBpmDefinitionKey());
        newProcessInstance.setCreateDate(new Date());
        newProcessInstance.setExternalKey(externalKey);
        newProcessInstance.setDescription(description);
        newProcessInstance.setKeyword(keyword);
        newProcessInstance.setStatus(ProcessStatus.NEW);

        {
            ProcessInstanceSimpleAttribute attr = new ProcessInstanceSimpleAttribute();
            attr.setKey("creator");
            attr.setValue(creator.getLogin());
            newProcessInstance.addAttribute(attr);

            attr = new ProcessInstanceSimpleAttribute();
            attr.setKey("creatorName");
            attr.setValue(creator.getRealName());
            newProcessInstance.addAttribute(attr);
        }
        ProcessInstanceSimpleAttribute attr = new ProcessInstanceSimpleAttribute();
        attr.setKey("source");
        attr.setValue(source);
        newProcessInstance.addAttribute(attr);

        ctx.getProcessInstanceDAO().saveProcessInstance(newProcessInstance);

        if(internalId == null)
          newProcessInstance = startProcessInstance(config, externalKey, ctx, newProcessInstance);
        else
          newProcessInstance.setInternalId(internalId);

        creator = findOrCreateUser(creator, ctx);

        ProcessInstanceLog log = new ProcessInstanceLog();
        log.setState(null);
        log.setEntryDate(Calendar.getInstance());
        log.setEventI18NKey("process.log.process-started");
        log.setUser(creator);
        log.setLogType(ProcessInstanceLog.LOG_TYPE_START_PROCESS);
        log.setOwnProcessInstance(newProcessInstance);
        newProcessInstance.getRootProcessInstance().addProcessLog(log);
        List<BpmTask> findProcessTasks = findProcessTasks(newProcessInstance, ctx);
        String taskName = findProcessTasks.get(0).getTaskName();


            newProcessInstance.setState(taskName);
        ctx.getProcessInstanceDAO().saveProcessInstance(newProcessInstance);

        Collection<IEvent> events = new ArrayList<IEvent>();
        events.add(new BpmEvent(Type.NEW_PROCESS, newProcessInstance, creator));

    List<BpmTask> processTasks = findProcessTasks(newProcessInstance, ctx);

    if (!processTasks.isEmpty()) {
      for (BpmTask task : processTasks)
      {
        events.add(new BpmEvent(Type.ASSIGN_TASK, task, creator));

        /* Inform queue manager about task assigne */
        ctx.getUserProcessQueueManager().onTaskAssigne(task);
      }
    }
    else {
      Collection<BpmTask> processTaskInQueues = getProcessTaskInQueues(ctx, newProcessInstance);

      for (BpmTask task : processTaskInQueues) {
        ctx.getUserProcessQueueManager().onQueueAssigne(new MutableBpmTask(task));
      }
    }

        for (IEvent event : events) {
            broadcastEvent(ctx, event);
        }
       

        return newProcessInstance;
    }

    protected void broadcastEvent(final ProcessToolContext ctx, final IEvent event) {
        eventBusManager.publish(event);
        if (substitutingUserEventBusManager != null)
            substitutingUserEventBusManager.publish(event);
        ctx.addTransactionCallback(new TransactionFinishedCallback() {
            @Override
            public void onFinished() {
                ctx.getEventBusManager().post(event);
            }
        });
    }

    protected UserData findOrCreateUser(UserData user, ProcessToolContext ctx) {
        return ctx.getUserDataDAO().findOrCreateUser(user);
    }

    protected Set<String> getPermissions(Collection<? extends AbstractPermission> col) {
        Set<String> res = new HashSet<String>();
        for (AbstractPermission permission : col) {
            if (hasMatchingRole(permission.getRoleName())) {
                res.add(permission.getPrivilegeName());
            }
        }
        return res;
    }

    public Set<String> getPermissionsForWidget(ProcessStateWidget widget, ProcessToolContext ctx) {
        return getPermissions(widget.getPermissions());
    }

    public Set<String> getPermissionsForAction(ProcessStateAction action, ProcessToolContext ctx) {
        return getPermissions(action.getPermissions());
    }

    public boolean hasPermissionsForDefinitionConfig(ProcessDefinitionConfig config) {
        if (config.getPermissions() == null || config.getPermissions().isEmpty()) {
            return true;
        }

        Pair<Collection<ProcessDefinitionPermission>, Collection<ProcessDefinitionPermission>> pair =
                Collections.halve(config.getPermissions(), new Predicate<ProcessDefinitionPermission>() {
                    @Override
                    public boolean apply(ProcessDefinitionPermission input) {
                        return PRIVILEGE_EXCLUDE.equalsIgnoreCase(input.getPrivilegeName());
                    }
                });

        Collection<ProcessDefinitionPermission> excludes = pair.getFirst();
        if (!excludes.isEmpty()) {
            ProcessDefinitionPermission permission = Collections.firstMatching(excludes, new Predicate<ProcessDefinitionPermission>() {
                @Override
                public boolean apply(ProcessDefinitionPermission input) {
                    return hasMatchingRole(input.getRoleName());
                }
            });
            if (permission != null) {
                return false;
            }
        }
        Collection<ProcessDefinitionPermission> includes = pair.getSecond();
        ProcessDefinitionPermission permission = Collections.firstMatching(includes, new Predicate<ProcessDefinitionPermission>() {
            @Override
            public boolean apply(ProcessDefinitionPermission input) {
                return hasMatchingRole(input.getRoleName());
            }
        });

        return permission != null || includes.isEmpty();
    }

    public EventBusManager getEventBusManager() {
        return eventBusManager;
    }

    public String getUserLogin() {
        return user.getLogin();
    }

    @Override
    public UserData getUser(ProcessToolContext ctx) {
        user = loadOrCreateUser(ctx, user);
        return user;
    }

    @Override
    public UserData loadOrCreateUser(ProcessToolContext ctx, UserData userData) {
        return findOrCreateUser(userData, ctx);
    }

    @Override
    public UserData getSubstitutingUser(ProcessToolContext ctx) {
        return substitutingUser != null ? findOrCreateUser(substitutingUser, ctx) : null;
    }

    @Override
    public ProcessInstance getProcessData(String internalId, ProcessToolContext ctx) {
        return ctx.getProcessInstanceDAO().getProcessInstanceByInternalId(internalId);
    }

    public ProcessInstance refreshProcessData(ProcessInstance pi, ProcessToolContext ctx) {
        return ctx.getProcessInstanceDAO().refreshProcessInstance(pi);
    }

    @Override
    public void saveProcessInstance(pl.net.bluesoft.rnd.processtool.model.ProcessInstance
                                                processInstance, ProcessToolContext ctx) {
        ctx.updateContext(processInstance);
        ctx.getProcessInstanceDAO().saveProcessInstance(processInstance);
    }

    protected abstract ProcessInstance startProcessInstance(ProcessDefinitionConfig config, String externalKey,
                                                            ProcessToolContext ctx, ProcessInstance pi);

    public Collection<ProcessDefinitionConfig> getAvailableConfigurations(ProcessToolContext ctx) {
        Collection<ProcessDefinitionConfig> activeConfigurations = ctx.getProcessDefinitionDAO().getActiveConfigurations();
        List<ProcessDefinitionConfig> res = new ArrayList<ProcessDefinitionConfig>();
        for (ProcessDefinitionConfig cfg : activeConfigurations) {
            if (cfg.getPermissions().isEmpty()) {
                res.add(cfg);
    }
            for (ProcessDefinitionPermission permission : cfg.getPermissions()) {
                String roleName = permission.getRoleName();
                if ("RUN".equals(permission.getPrivilegeName()) && roleName != null && hasMatchingRole(roleName)) {
                    res.add(cfg);
                    break;
                }
            }
        }
        java.util.Collections.sort(res, ProcessDefinitionConfig.DEFAULT_COMPARATOR);
        return res;
    }

    protected Collection<ProcessQueue> getUserQueuesFromConfig(ProcessToolContext ctx) {

        return new Mapcar<ProcessQueueConfig, ProcessQueue>(ctx.getProcessDefinitionDAO().getQueueConfigs()) {
            @Override
            public ProcessQueue lambda(ProcessQueueConfig x) {

                if (x.getRights().isEmpty()) {
                    return transform(x, false);
                }
                boolean found = false;
                boolean browsable = false;
                for (ProcessQueueRight r : x.getRights()) {
                    String rn = r.getRoleName();
                    if (rn == null) {
                        continue;
                    }

                    if (hasMatchingRole(rn)) {
                        found = true;
                        browsable = browsable || r.isBrowseAllowed();
                    }
                }
                if (found) {
                    return transform(x, browsable);
                }
                return null;
            }

            ProcessQueue transform(ProcessQueueConfig x, boolean browsable) {
                ProcessQueue pq = new ProcessQueue();
                pq.setBrowsable(browsable);
                pq.setName(x.getName());
                pq.setDescription(x.getDescription());
                pq.setProcessCount(0);
                pq.setUserAdded(x.getUserAdded());
                return pq;
            }
        }.go();
    }

    private boolean hasMatchingRole(String roleName) {
        for (String role : roleNames) {
            if (role != null && role.matches(roleName)) {
                return true;
            }
        }
        return false;
    }

    protected ProcessToolContext getCurrentContext() {
        return ProcessToolContext.Util.getThreadProcessToolContext();
    }


    @Override
    public Collection<String> getRoleNames() {
        return roleNames;
    }

}
TOP

Related Classes of pl.net.bluesoft.rnd.processtool.bpm.impl.AbstractProcessToolSession

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.