/** * The implementation of the task parent interface. * * @author Sebastian Wagner * @author Tobias Unger */ @Transactional public class TaskParentInterfaceImpl implements TaskParentInterface { @Autowired protected IDataAccessProvider dataAccessProvider; protected EventHandler evenHandler; protected Logger log = Utilities.getLogger(this.getClass()); @Autowired private TaskInstanceFactory taskInstanceFactory; @Autowired private WorkItemFactory workItemFactory; @Autowired private IAuthorizationManager authorizationManager; /** * Creates a new {@link TaskParentInterfaceImpl} object.</b> It initializes the {@link * IDataAccessProvider}</b> Moreover all timers are reactivated (e.g. suspend until timer, * expiration timer). See {@link TaskInstanceTimers} for more information. */ public TaskParentInterfaceImpl() { // this.dataAccessProvider = IDataAccessProvider.Factory.newInstance(); this.evenHandler = EventHandler.newInstance(); /* * Reactivate all task instance timers (e.g. suspend until timer, * expiration timer) i.e. schedule the execution of certain actions * until their timer has expired. */ TaskInstanceTimers.reactivateTimers(); } /* * (non-Javadoc) * * @see com.htm.TaskParentInterface#createTaskInstance(java.lang.String, * java.lang.String, java.lang.Object, java.util.Set, java.lang.String, * java.sql.Timestamp) */ public String createTaskInstance( String taskParentId, Set<ICorrelationProperty> correlationProperties, String taskModelName, String taskInstanceName, Object inputData, Set<IAttachment> attachments, Timestamp expirationTime) throws HumanTaskManagerException { try { // TODO contextId String initiatorUserId = getCurrentUser(); if (StringUtils.isEmpty(initiatorUserId)) { String errorMsg = "The username of the task initiator could not be determined."; log.error(errorMsg); throw new HumanTaskManagerException(errorMsg); } /* Start transaction for creating a task instance */ dataAccessProvider.beginTx(); this.authorizationManager.authorizeTaskParentAction( initiatorUserId, null, EActions.CREATE_TASK_INSTANCE); /* Create the task instance model */ TaskInstanceFactory taskFac = this.taskInstanceFactory; ITaskInstance taskInstance = taskFac.createTaskInstance( taskModelName, taskInstanceName, inputData, taskParentId, correlationProperties, expirationTime); /* Store the task instance instance */ dataAccessProvider.persistHumanTaskInstance(taskInstance); // Audit // if (Configuration.isLoggingEnabled()) { // IAuditLogger auditLogger = AuditFactory.newInstance(); // TaskInstanceView taskInstanceView = new // TaskInstanceView(taskInstance); // AuditAction action = new // AuditAction(EActions.CREATE_TASK_INSTANCE.toString(), // taskInstanceView, taskInstanceView.getStatus(), null, // initiatorUserId); // auditLogger.logAction(action); // } /* Activate the task instance expiration timer. */ TaskInstanceTimers.activateExpirationTimer(taskInstance); /* * Create Work Items and add attachments */ List<IWorkItem> workItems = new ArrayList<IWorkItem>(); WorkItemFactory workItemFac = this.workItemFactory; /* * A single work item for the task initiator has to be created * because she is not defined in the task model by a people query. * This should be done before the other work items are created since * the people queries in the task model could refer on the task * initiator. */ workItems.add( workItemFac.createNewWorkItem(initiatorUserId, EHumanRoles.TASK_INITIATOR, taskInstance)); /* * The attachments should also be added before the other work items * are created then the people queries can refer on the attachments. */ taskInstance.setAttachments( this.taskInstanceFactory.createAssignedUser(initiatorUserId), attachments); /* * Create work items for roles that are defined via people queries * within the task model i.e. for roles business administrators, * task stakeholder, potential owners */ workItems.addAll(workItemFac.createWorkItemsForTaskInstance(taskInstance)); // TODO: evaluate QueryProperties taskFac.evaluateQueryProperties(taskInstance.getId(), taskModelName); /* * If the task instance has one or more potential owners it * transitions to ready state i.e. it is activated */ boolean hasPotentialOwner = taskInstance.hasPotentialOwners(); log.debug("Create task instance - Task instance has potential owners : " + hasPotentialOwner); /* * The task instance can only set to the READY state if it has * potential owners and if the task instance is not already expired. */ String oldState = taskInstance.getStatus().toString(); if (taskInstance.hasPotentialOwners() && !taskInstance.isExpired()) { taskInstance.setStatus(ETaskInstanceState.READY); taskInstance.setActivationTime(new Timestamp(Calendar.getInstance().getTimeInMillis())); // TODO only one potential owner -> immediately go to reserved // state } if (!hasPotentialOwner) { log.info( "Create task instance - " + "Can't transition to '" + ETaskInstanceState.READY + "' state because no potential owner(s) were found."); } if (taskInstance.isExpired()) { log.info( "Create task instance - " + "The task instance is " + ETaskInstanceState.OBSOLETE + " created because it has already expired at '" + Utilities.formatTimestamp(expirationTime) + "'."); } dataAccessProvider.persistWorkItems(workItems); /* Inform event subscriber about the new work items */ publishNewWorkItemEvent(workItems); // Audit if (Configuration.isLoggingEnabled()) { IAuditLogger auditLogger = AuditFactory.newInstance(); TaskInstanceView taskInstanceView = new TaskInstanceView(taskInstance); AuditAction action = new AuditAction( EActions.CREATE_TASK_INSTANCE.toString(), taskInstanceView, taskInstanceView.getStatus(), oldState, initiatorUserId); auditLogger.logAction(action); } dataAccessProvider.commitTx(); return taskInstance.getId(); } catch (HumanTaskManagerException e) { dataAccessProvider.rollbackTx(); throw e; } finally { dataAccessProvider.close(); } } /* * (non-Javadoc) * * @see com.htm.TaskParentInterface#exit(java.lang.String) */ public void exit(String tiid) throws HumanTaskManagerException { try { /* Start transaction for creating a task instance */ dataAccessProvider.beginTx(); log.debug("Exit task instance - Trying to exit task instance '" + tiid + "'"); this.authorizationManager.authorizeTaskParentAction(getCurrentUser(), tiid, EActions.EXIT); ITaskInstance taskInstance = dataAccessProvider.getTaskInstance(tiid); String oldState = taskInstance.getStatus().toString(); // TODO for skipped, completed, faulted task instances an individual // error message should // be created. Currently only an invalidarguemntexception is thrown if (taskInstance.isExpired()) { String errorMsg = "The task instance '" + taskInstance.getId() + "' can not be exited " + "because it expired on " + Utilities.formatTimestamp(taskInstance.getExpirationTime()); log.error(errorMsg); throw new InvalidOperationException(errorMsg); } taskInstance.setStatus(ETaskInstanceState.EXITED); // Audit if (Configuration.isLoggingEnabled()) { IAuditLogger auditLogger = AuditFactory.newInstance(); TaskInstanceView taskInstanceView = new TaskInstanceView(taskInstance); AuditAction action = new AuditAction( EActions.EXIT.toString(), taskInstanceView, taskInstanceView.getStatus(), oldState, SessionUtils.getCurrentUser()); auditLogger.logAction(action); } dataAccessProvider.commitTx(); } catch (HumanTaskManagerException e) { dataAccessProvider.rollbackTx(); throw e; } finally { dataAccessProvider.close(); } } /* * (non-Javadoc) * * @see com.htm.ITaskManagerLogin#login(java.lang.String, java.lang.String) */ @Deprecated public String login(String userid, String password) throws AuthenticationException { return null; } protected String getCurrentUser() throws UserException { return SessionUtils.getCurrentUser(); } protected void publishNewWorkItemEvent(List<IWorkItem> workItems) { if (workItems != null) { Iterator<IWorkItem> iter = workItems.iterator(); /* * Create an event for each work item that was created and inform * the subscribers about it */ while (iter.hasNext()) { evenHandler.notifySubscribers( new CreateWorkItemEvent(new WorkItemView((IWorkItem) iter.next()))); } } } }
@Ignore public class StructureTestTask { EOperations state; int strNr = 0; boolean locked = false; boolean controlled = false; StructureTestTask parentTask = null; StructureTestTask mergeTask = null; List<StructureTestTask> subTasks = new ArrayList<StructureTestTask>(); List<StructureTestTask> controlledTasks = new ArrayList<StructureTestTask>(); private Logger log = Utilities.getLogger(this.getClass()); public StructureTestTask() {} public StructureTestTask(boolean locked) { this.locked = locked; } public void setLock(boolean locked) { this.locked = locked; } public void setControll(boolean controlled) { this.controlled = controlled; } public void addSubTask(StructureTestTask subTask) { subTask.setParentTask(this); int max = 0; for (StructureTestTask childTask : this.getSubTasks()) { if (childTask.getStrNr() > max) { max = childTask.getStrNr(); } } subTask.setStrNr(max + 1); this.subTasks.add(subTask); } public StructureTestTask getMergeTaskCopy() { StructureTestTask copy = new StructureTestTask(); for (StructureTestTask controlledTask : this.getControlledTasks()) { copy.addControlledTask(controlledTask.getMergeTaskCopy()); } return copy; } public void removeSubTask(StructureTestTask subTask) { subTask.setParentTask(null); this.subTasks.remove(subTask); } public void removeControlledTask(StructureTestTask controlledTask) { controlledTask.setMergeTask(null); controlledTask.setControll(false); this.controlledTasks.remove(controlledTask); } public void addControlledTask(StructureTestTask controlledTask) { controlledTask.setMergeTask(this); controlledTask.setControll(true); this.controlledTasks.add(controlledTask); } public List<StructureTestTask> getSubTasks() { return this.subTasks; } public List<StructureTestTask> getControlledTasks() { return this.controlledTasks; } private void setParentTask(StructureTestTask parentTask) { this.parentTask = parentTask; } private void setMergeTask(StructureTestTask mergeTask) { this.mergeTask = mergeTask; } public int getStrNr() { return this.strNr; } public void setStrNr(int strNr) { this.strNr = strNr; } public static int getTotalMergeTaskCount(String tiid, IStructuredTaskClientInterface stci) throws HumanTaskManagerException { List<String> controlledTasks = stci.getControlledTasks(tiid); int count = controlledTasks.size(); for (String controlledTask : controlledTasks) { count = count + getTotalMergeTaskCount(controlledTask, stci); } return count; } public static int getTotalTestMergeTaskCount( StructureTestTask task, IStructuredTaskClientInterface stci) { List<StructureTestTask> controlledTasks = task.getControlledTasks(); int count = controlledTasks.size(); for (StructureTestTask controlledTask : controlledTasks) { count = count + getTotalTestMergeTaskCount(controlledTask, stci); } return count; } public boolean verifyStructure(String tiid, IStructuredTaskClientInterface stci) throws HumanTaskManagerException { log.info("Verify Structure of Task " + tiid); StructuredTaskInstanceView task = stci.getStructuredTaskInfo(tiid); if (task.isLocked() != this.locked) { log.warn("Locking state of Task " + tiid + " is not correct (" + this.locked + ")"); return false; } if (task.isControlled() != this.controlled) { log.warn("Controll state of Task " + tiid + " is not correct (" + this.controlled + ")"); return false; } log.info("Locked and Controll state of Task " + tiid + " is correct"); if (getTotalMergeTaskCount(tiid, stci) != getTotalTestMergeTaskCount(this, stci)) { log.info("!!!Merge Task size is not correct!!!"); return false; } log.info( "Total merge task size of Task " + tiid + " correct (" + getTotalTestMergeTaskCount(this, stci) + ")"); List<String> subTasks = stci.getSubTasks(tiid); if (subTasks.size() == this.getSubTasks().size()) { for (StructureTestTask testSubTask : this.getSubTasks()) { String subTask = stci.getSubTaskByStructureNr(tiid, testSubTask.getStrNr()); log.info("Sub Task " + subTask + " correctly found"); if (!testSubTask.verifyStructure(subTask, stci)) { return false; } } } else { log.info("!!!Sub Task size is not correct!!!"); return false; } return true; } }