/*
* Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wso2.carbon.humantask.core.engine.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.wso2.carbon.humantask.*;
import org.wso2.carbon.humantask.core.HumanTaskConstants;
import org.wso2.carbon.humantask.core.api.event.TaskEventInfo;
import org.wso2.carbon.humantask.core.api.event.TaskInfo;
import org.wso2.carbon.humantask.core.api.scheduler.Scheduler;
import org.wso2.carbon.humantask.core.dao.*;
import org.wso2.carbon.humantask.core.dao.jpa.openjpa.model.Deadline;
import org.wso2.carbon.humantask.core.dao.jpa.openjpa.model.GenericHumanRole;
import org.wso2.carbon.humantask.core.engine.PeopleQueryEvaluator;
import org.wso2.carbon.humantask.core.engine.runtime.ExpressionEvaluationContext;
import org.wso2.carbon.humantask.core.engine.runtime.api.EvaluationContext;
import org.wso2.carbon.humantask.core.engine.runtime.api.ExpressionLanguageRuntime;
import org.wso2.carbon.humantask.core.engine.runtime.api.HumanTaskRuntimeException;
import org.wso2.carbon.humantask.core.internal.HumanTaskServiceComponent;
import org.wso2.carbon.humantask.core.store.HumanTaskBaseConfiguration;
import org.wso2.carbon.humantask.core.store.HumanTaskStore;
import org.wso2.carbon.humantask.core.store.TaskConfiguration;
import org.wso2.carbon.humantask.core.utils.Duration;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.user.core.UserRealm;
import org.wso2.carbon.user.core.UserStoreException;
import javax.xml.namespace.QName;
import java.util.*;
/**
* Common utility method for all the TaskDAO objects.
*/
public final class CommonTaskUtil {
private CommonTaskUtil() {
}
private static final Log log = LogFactory.getLog(CommonTaskUtil.class);
/**
* Checks whether the provided task has sub tasks.
*
* @param task : The TaskDAO object.
* @return : True if the task has sub tasks. false otherwise.
*/
public static Boolean hasSubTasks(TaskDAO task) {
Boolean hasSubTasks = false;
if (task.getSubTasks() != null && task.getSubTasks().size() > 0) {
hasSubTasks = true;
}
return hasSubTasks;
}
/**
* Checks whether the provided task has sub tasks.
*
* @param task : The TaskDAO object.
* @return : True if the task has sub tasks. false otherwise.
*/
public static Boolean hasAttachments(TaskDAO task) {
Boolean hasAttachments = false;
if (task.getAttachments() != null && task.getAttachments().size() > 0) {
hasAttachments = true;
}
return hasAttachments;
}
/**
* Checks whether the provided task has sub tasks.
*
* @param task : The TaskDAO object.
* @return : True if the task has sub tasks. false otherwise.
*/
public static Boolean hasComments(TaskDAO task) {
Boolean hasComments = false;
if (task.getComments() != null && task.getComments().size() > 0) {
hasComments = true;
}
return hasComments;
}
/**
* Checks whether the provided task has sub tasks.
*
* @param task : The TaskDAO object.
* @return : True if the task has sub tasks. false otherwise.
*/
public static Boolean hasOutput(TaskDAO task) {
Boolean hasOutput = false;
if (task.getOutputMessage() != null) {
hasOutput = true;
}
return hasOutput;
}
/**
* Checks whether the provided task has sub tasks.
*
* @param task : The TaskDAO object.
* @return : True if the task has sub tasks. false otherwise.
*/
public static Boolean hasFault(TaskDAO task) {
Boolean hasFailure = false;
if (task.getFailureMessage() != null) {
hasFailure = true;
}
return hasFailure;
}
/**
* Gets the task configuration object for the given task.
*
* @param task :
* @return : The task configuration object.
*/
public static HumanTaskBaseConfiguration getTaskConfiguration(TaskDAO task) {
HumanTaskStore taskStore = HumanTaskServiceComponent.getHumanTaskServer().
getTaskStoreManager().getHumanTaskStore(task.getTenantId());
return taskStore.getTaskConfiguration(QName.valueOf(task.getName()));
}
/**
* Checks whether the given TaskDAO has potential owners.
*
* @param task : The task to be checked for potential owners.
* @return : true if the task has potential owners.
*/
public static boolean hasPotentialOwners(TaskDAO task) {
PeopleQueryEvaluator pqe = HumanTaskServiceComponent.getHumanTaskServer().
getTaskEngine().getPeopleQueryEvaluator();
boolean hasPotentialOwners = false;
for (GenericHumanRoleDAO humanRoleDAO : task.getHumanRoles()) {
if (GenericHumanRoleDAO.GenericHumanRoleType.POTENTIAL_OWNERS.
equals(humanRoleDAO.getType()) && humanRoleDAO.getOrgEntities() != null &&
humanRoleDAO.getOrgEntities().size() > 0) {
try {
pqe.checkOrgEntitiesExist(humanRoleDAO.getOrgEntities());
hasPotentialOwners = true;
} catch (HumanTaskRuntimeException ex) {
hasPotentialOwners = false;
}
}
}
return hasPotentialOwners;
}
/**
* Gets the single user for a given role.
* Note : this method is applicable for roles which has only one OrganizationalEntityDAO under it
* Example : task initiator and actual owner.
*
* @param task : The task DAO object.
* @param type : The role type of the user.
* @return : The name of the actual owner of the task.
*/
public static OrganizationalEntityDAO getUserEntityForRole(TaskDAO task,
GenericHumanRoleDAO.GenericHumanRoleType type) {
OrganizationalEntityDAO matchingUser = null;
for (GenericHumanRoleDAO humanRoleDAO : task.getHumanRoles()) {
if (type.equals(humanRoleDAO.getType()) && humanRoleDAO.getOrgEntities() != null &&
humanRoleDAO.getOrgEntities().size() == 1) {
matchingUser = humanRoleDAO.getOrgEntities().get(0);
break;
}
}
return matchingUser;
}
/**
* Gets a list of OrganizationalEntityDAO for the given task and the role type.
*
* @param task : The TaskDAO.
* @param type : The GenericHumanRoleType for which the OrganizationalEntityDAO list to be retrieved.
* @return : The list of OrganizationalEntityDAOs
*/
public static List<OrganizationalEntityDAO> getOrgEntitiesForRole(TaskDAO task,
GenericHumanRoleDAO.GenericHumanRoleType type) {
List<OrganizationalEntityDAO> matchingOrgEntities = new ArrayList<OrganizationalEntityDAO>();
if (task != null && type != null) {
for (GenericHumanRoleDAO humanRoleDAO : task.getHumanRoles()) {
if (humanRoleDAO.getType().equals(type) && humanRoleDAO.getOrgEntities() != null) {
matchingOrgEntities.addAll(humanRoleDAO.getOrgEntities());
break;
}
}
}
return matchingOrgEntities;
}
/**
* Gets the default presentation name of tha task.
*
* @param task : The task object.
* @return : The default presentation name if there's any, null otherwise.
*/
public static PresentationNameDAO getDefaultPresentationName(TaskDAO task) {
PresentationNameDAO defaultPresentationName = null;
if (task.getPresentationNames() != null && task.getPresentationNames().size() > 0) {
if (task.getPresentationNames().size() == 1) {
defaultPresentationName = task.getPresentationNames().get(0);
} else {
for (PresentationNameDAO presentationName : task.getPresentationNames()) {
if (StringUtils.isNotEmpty(presentationName.getXmlLang()) &&
presentationName.getXmlLang().toLowerCase().contains("en")) {
defaultPresentationName = presentationName;
break;
}
}
}
// if at this point we cannot get the default presentation name we'd return the first
// as the task presentation name.
if (defaultPresentationName == null) {
task.getPresentationNames().get(0);
}
}
return defaultPresentationName;
}
/**
* @param task TaskDAO
* @return PresentationSubjectDAO
*/
public static PresentationSubjectDAO getDefaultPresentationSubject(TaskDAO task) {
PresentationSubjectDAO defaultPresentationSubject = null;
if (task.getPresentationSubjects() != null && task.getPresentationSubjects().size() > 0) {
if (task.getPresentationSubjects().size() == 1) {
defaultPresentationSubject = task.getPresentationSubjects().get(0);
} else {
for (PresentationSubjectDAO subject : task.getPresentationSubjects()) {
if (StringUtils.isNotEmpty(subject.getXmlLang()) &&
subject.getXmlLang().toLowerCase().contains("en")) {
defaultPresentationSubject = subject;
break;
}
}
}
// if at this point we cannot get the default presentation subject we'd return the first
// as the task presentation subject.
if (defaultPresentationSubject == null) {
task.getPresentationSubjects().get(0);
}
}
return defaultPresentationSubject;
}
/**
* Returns the default presentation description of the task.
*
* @param task : The task object
* @return : The default presentation description.
*/
public static PresentationDescriptionDAO getDefaultPresentationDescription(TaskDAO task) {
PresentationDescriptionDAO presentationDescriptionDAO = null;
if (task.getPresentationDescriptions() != null && task.getPresentationDescriptions().size() > 0) {
if (task.getPresentationDescriptions().size() == 1) {
presentationDescriptionDAO = task.getPresentationDescriptions().get(0);
} else {
for (PresentationDescriptionDAO description : task.getPresentationDescriptions()) {
if (StringUtils.isNotEmpty(description.getXmlLang()) &&
description.getXmlLang().toLowerCase().contains("en")) {
presentationDescriptionDAO = description;
break;
}
}
}
// if at this point we cannot get the default presentation description we'd return the first
// as the task presentation subject.
if (presentationDescriptionDAO == null) {
task.getPresentationDescriptions().get(0);
}
}
return presentationDescriptionDAO;
}
/**
* Get Rendering types.
* @param task : task entity class
* @param taskConfiguration : HumanTask base configuration
* @return : available task renderings QNames.
*/
public static QName[] getRenderingTypes(TaskDAO task, HumanTaskBaseConfiguration taskConfiguration) {
TRenderings renderings = taskConfiguration.getRenderings();
List<QName> renderingQNames = new ArrayList<QName>();
if (renderings != null && renderings.getRenderingArray() != null && renderings.getRenderingArray().length > 0) {
for(TRendering rendering: renderings.getRenderingArray()){
renderingQNames.add(rendering.getType());
}
}
return null;
}
/**
* Returns rendering elements for given rendering type.
*
* @param task : TaskDAO
* @param taskConfiguration : HumanTask base configuration
* @param renderingType : QName of the rendering type.
* @return
*/
public static String getRendering(TaskDAO task, HumanTaskBaseConfiguration taskConfiguration, QName renderingType) {
String htdPrefix = taskConfiguration.getNamespaceContext().getPrefix(HumanTaskConstants.HTD_NAMESPACE) + ":";
EvaluationContext evalCtx = new ExpressionEvaluationContext(task, taskConfiguration);
if (renderingType != null) {
String expressionLanguage = taskConfiguration.getExpressionLanguage();
ExpressionLanguageRuntime expLangRuntime = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine()
.getExpressionLanguageRuntime(
expressionLanguage);
TRendering rendering = taskConfiguration.getRendering(renderingType);
if (rendering != null) {
// Replace Presentation params with values.
// Do not trim, to avoid malformed html. Renderings elements can contains html elements.
String processedString = replaceUsingPresentationParams(task.getPresentationParameters(),
rendering.xmlText());
// Evaluating xpaths with $ $ marks..
try {
if (processedString.contains("$htd")) {
String[] split = processedString.split("\\$");
if (split != null && split.length > 0) {
StringBuilder sm = new StringBuilder();
// Assume xpath replaced initially, to avoid adding $ to start of the xml.
// TODO : Improve this logic.
boolean xpathReplaced = true;
for (String s : split) {
if (s.startsWith(htdPrefix)) {
String value = expLangRuntime.evaluateAsString(s, evalCtx);
sm.append(value);
xpathReplaced = true;
} else {
if(xpathReplaced == true) {
// xpath replaced.
sm.append(s);
}else {
// This is not a xpath. Adding $ and split content back.
sm.append("$").append(s);
}
xpathReplaced = false;
}
}
processedString = sm.toString();
}
}
} catch (Exception ex) {
log.error("Error while evaluating rendering xpath. Please review xpath and deploy " +
task.getDefinitionName() + "task again.", ex);
}
return processedString;
} else {
if (log.isDebugEnabled()) {
log.debug("Rendering type " + renderingType + " Not found for task definition " +
taskConfiguration.getName());
}
}
}
return "";
}
/**
* Nominates the given task to a matching actual owner, if there's only 1 user in the potential owners list. In that case
* the task status would be set to RESERVED. If there are more than 1 user only the task status would be set to READY.
*
* @param task : The task to be nominated.
* @param pqe : The people query evaluator for people queries.
*/
public static void nominate(TaskDAO task, PeopleQueryEvaluator pqe) {
//we can nominate only if there's no specified activation time or the provided activation time has expired.
if (!TaskType.NOTIFICATION.equals(task.getType())) {
if (task.getActivationTime() == null || !task.getActivationTime().after(new Date())) {
GenericHumanRoleDAO potentialOwners =
task.getGenericHumanRole(GenericHumanRoleDAO.GenericHumanRoleType.POTENTIAL_OWNERS);
boolean hasMultipleOwners = hasMultiplePotentialOwners(potentialOwners, pqe);
if(hasMultipleOwners)
{
task.setStatus(TaskStatus.READY);
if(log.isDebugEnabled())
{
log.debug("Task " + task.getId() +" has multiple potential owners. Task Status -> READY");
}
}else {
for (OrganizationalEntityDAO orgEntity : potentialOwners.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.GROUP.equals(
orgEntity.getOrgEntityType())) {
String roleName = orgEntity.getName();
if (pqe.isExistingRole(roleName) &&
pqe.getUserNameListForRole(roleName).size() == 1) {
// There's only 1 user matching for potential owners. so we can safely reserve the
// task for that particular user. since hasMultipleOwners is false
GenericHumanRoleDAO actualOwnerRole = pqe.createGHRForRoleName(roleName,
GenericHumanRoleDAO.GenericHumanRoleType.ACTUAL_OWNER);
actualOwnerRole.setTask(task);
task.addHumanRole(actualOwnerRole);
task.setStatus(TaskStatus.RESERVED);
if(log.isDebugEnabled())
{
log.debug("Task " + task.getId() +" has one potential owner from a GroupOrgEntity. Task Status -> RESERVED");
}
break;
}
} else if (OrganizationalEntityDAO.OrganizationalEntityType.USER.equals(
orgEntity.getOrgEntityType())) {
//since hasMultipleOwners is false, this user is only available user.
String actualOwner = orgEntity.getName();
GenericHumanRoleDAO actualOwnerRole =
pqe.createGHRForUsername(actualOwner, GenericHumanRole.GenericHumanRoleType.ACTUAL_OWNER);
actualOwnerRole.setTask(task);
task.addHumanRole(actualOwnerRole);
task.setStatus(TaskStatus.RESERVED);
if(log.isDebugEnabled())
{
log.debug("Task " + task.getId() +" has one potential owner from a UserOrgEntity.. Task Status -> RESERVED");
}
break;
}
}
}
}
}
}
private static boolean hasMultiplePotentialOwners(GenericHumanRoleDAO ghr,
PeopleQueryEvaluator pqe) {
int counter = 0;
for (OrganizationalEntityDAO orgEntity : ghr.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.USER.equals(
orgEntity.getOrgEntityType()) && pqe.isExistingUser(orgEntity.getName())) {
counter++;
} else if (OrganizationalEntityDAO.OrganizationalEntityType.GROUP.equals(
orgEntity.getOrgEntityType()) && pqe.isExistingRole(orgEntity.getName())) {
List<String> userList = pqe.getUserNameListForRole(orgEntity.getName());
counter = counter + userList.size();
}
if (counter > 1) {
return true;
}
}
return (counter > 1);
}
/**
* Calculates the task priority.
*
* @param taskConfig : The task's configuration
* @param evalCtx : The evaluation context.
* @return : The task priority
*/
public static int calculateTaskPriority(HumanTaskBaseConfiguration taskConfig,
EvaluationContext evalCtx) {
TPriorityExpr priorityDef = taskConfig.getPriorityExpression();
int taskPriorityInt = HumanTaskConstants.DEFAULT_TASK_PRIORITY;
if (priorityDef != null) {
String expLang = priorityDef.getExpressionLanguage() == null ?
taskConfig.getExpressionLanguage() :
priorityDef.getExpressionLanguage();
ExpressionLanguageRuntime expLangRuntime = HumanTaskServiceComponent.getHumanTaskServer().
getTaskEngine().getExpressionLanguageRuntime(expLang);
Number priority = expLangRuntime.evaluateAsNumber(priorityDef.newCursor().
getTextValue().trim(), evalCtx);
if (priority.intValue() > 10 || priority.intValue() < 0) {
log.warn(String.format(
"Ignoring the task priority value :[%d] The task priority has to be with 0 and 10. Setting to default:[%d].",
priority.intValue(), HumanTaskConstants.DEFAULT_TASK_PRIORITY));
} else {
taskPriorityInt = priority.intValue();
}
}
return taskPriorityInt;
}
/**
* Calculates the Role.
*
* @param evalCtx : The evaluation context.
* @param roleExpression : the role expression
* @param expressionLanguage : Expression language associated with the argument named "role"
* @return : The task priority
*/
public static String calculateRole(EvaluationContext evalCtx, String roleExpression,
String expressionLanguage) {
ExpressionLanguageRuntime expLangRuntime = HumanTaskServiceComponent.getHumanTaskServer().
getTaskEngine().getExpressionLanguageRuntime(expressionLanguage);
String role = expLangRuntime.evaluateAsString(roleExpression, evalCtx);
if (role == null) {
log.warn(String.format("Role cannot be null"));
}
return role;
}
/**
* Replace the presentation param values with the exact values matching for this task instance.
*
* @param presentationParameters : The list of presentation parameters for the task.
* @param expression : The expression to be replaces/
* @return : The processed string.
*/
public static String replaceUsingPresentationParams(
List<PresentationParameterDAO> presentationParameters,
String expression) {
String result;
result = expression.replaceAll("\\{\\{", "{");
result = result.replaceAll("\\}\\}", "}");
for (PresentationParameterDAO param : presentationParameters) {
result = result.replaceAll("\\{\\$" + param.getName() + "\\}", param.getValue());
}
// According to the samples of the spec we need to support $paramName$ kind of replacements as well.
for (PresentationParameterDAO param : presentationParameters) {
result = result.replaceAll("\\$" + param.getName() + "\\$", param.getValue());
}
return result;
}
/**
* Sets the task object to input message.
*
* @param task: The task.
*/
public static void setTaskToMessage(TaskDAO task) {
task.getInputMessage().setTask(task);
}
/**
* Returns the element with the given name.
*
* @param inputMessage : The input message.
* @param partName : The part name for which the data element is required.
* @return : The matching element.
*/
public static Element getMessagePart(MessageDAO inputMessage, String partName) {
Element node = inputMessage.getBodyData();
if (node.hasChildNodes()) {
Element matchingElement = null;
if(node.getElementsByTagName(partName).getLength() > 0) {
matchingElement = (Element) node.getElementsByTagName(partName).item(0);
}
if (matchingElement != null && matchingElement.getFirstChild() != null) {
return (Element) matchingElement.getFirstChild();
}
return matchingElement;
} else {
throw new HumanTaskRuntimeException("The input message does not have any child elements");
}
}
/**
* Process the deadlines for the given task.
*
* @param task : The task object.
* @param taskConf : The task configuration for this task.
* @param evalContext : The task's eval context.
*/
public static void processDeadlines(TaskDAO task, TaskConfiguration taskConf,
EvaluationContext evalContext) {
//TODO is it possible to process deadlines once per a task definition and set the duration per a task instance?
TDeadlines deadlines = taskConf.getDeadlines();
if (deadlines != null) {
TDeadline[] startDeadlines = deadlines.getStartDeadlineArray();
TDeadline[] completionDeadlines = deadlines.getCompletionDeadlineArray();
for (TDeadline deadline : startDeadlines) {
DeadlineDAO startDeadline = HumanTaskServiceComponent.getHumanTaskServer().
getTaskEngine().getDaoConnectionFactory().getConnection().createDeadline();
startDeadline.setStatus(TaskStatus.IN_PROGRESS);
startDeadline.setName((deadline.getName() == null ? "startDeadline" : deadline.getName()));
startDeadline.setTask(task);
startDeadline.setDeadlineDate(calculateDeadline(task, deadline, taskConf, evalContext).getTime());
task.addDeadline(startDeadline);
}
for (TDeadline deadline : completionDeadlines) {
Deadline completionDeadline = new Deadline();
completionDeadline.setStatus(TaskStatus.COMPLETED);
completionDeadline.setName((deadline.getName() == null ? "completionDeadline" : deadline.getName()));
completionDeadline.setTask(task);
completionDeadline.setDeadlineDate(calculateDeadline(task, deadline, taskConf, evalContext).
getTime());
task.addDeadline(completionDeadline);
}
}
}
private static Calendar calculateDeadline(TaskDAO taskDAO, TDeadline deadline,
TaskConfiguration taskConf,
EvaluationContext evalCtx) {
if (deadline.getUntil() != null) {
String expLang = deadline.getUntil().getExpressionLanguage() == null ?
taskConf.getExpressionLanguage() :
deadline.getUntil().getExpressionLanguage();
return HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().
getExpressionLanguageRuntime(expLang).evaluateAsDate(deadline.getUntil().
newCursor().getTextValue(), evalCtx);
} else if (deadline.getFor() != null) {
String expLang = deadline.getFor().getExpressionLanguage() == null ?
taskConf.getExpressionLanguage() :
deadline.getFor().getExpressionLanguage();
Duration duration = HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().
getExpressionLanguageRuntime(expLang).evaluateAsDuration(deadline.getFor().
newCursor().getTextValue(), evalCtx);
Calendar durationCalendar = Calendar.getInstance();
durationCalendar.setTime(taskDAO.getActivationTime());
duration.addTo(durationCalendar);
return durationCalendar;
}
return null;
}
/**
* Schedule deadlines for the given task.
*
* @param task : the task object.
*/
public static void scheduleDeadlines(TaskDAO task) {
List<DeadlineDAO> deadlines = task.getDeadlines();
for (DeadlineDAO deadline : deadlines) {
HumanTaskServiceComponent.getHumanTaskServer().getTaskEngine().getScheduler().
scheduleJob(System.currentTimeMillis(), deadline.getDeadlineDate().getTime(),
Scheduler.JobType.TIMER_DEADLINE, null, task.getId(), deadline.getName());
}
}
/**
* Gets the potential owner role name for the given task.
*
* @param task : The task object.
* @return : The potential owner role name.
*/
public static String getPotentialOwnerRoleName(TaskDAO task) {
String roleName = null;
GHR_ITERATION:
for (GenericHumanRoleDAO role : task.getHumanRoles()) {
if (GenericHumanRoleDAO.GenericHumanRoleType.POTENTIAL_OWNERS.equals(role.getType())) {
for (OrganizationalEntityDAO orgEntity : role.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.GROUP.equals(orgEntity.getOrgEntityType())) {
roleName = orgEntity.getName();
break GHR_ITERATION;
}
}
}
}
return roleName;
}
/**
* Gets the potential owner role name List for the given task.
* @param task : The task object.
* @return : The potential owner role name list.
*/
public static List<String> getGenericHumanRoleGroupList(TaskDAO task , GenericHumanRoleDAO.GenericHumanRoleType genericHumanRoleType) {
List<String> roleNameList = new ArrayList<String>();
for (GenericHumanRoleDAO role : task.getHumanRoles()) {
if (genericHumanRoleType.equals(role.getType())) {
for (OrganizationalEntityDAO orgEntity : role.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.GROUP.equals(orgEntity.getOrgEntityType())) {
roleNameList.add(orgEntity.getName());
}
}
}
}
return roleNameList;
}
/**
* Gets the potential owner role name List for the given task.
* @param task : The task object.
* @return : The potential owner role name list.
*/
public static Set<String> getGenericHumanRoleUserList(TaskDAO task , GenericHumanRoleDAO.GenericHumanRoleType genericHumanRoleType) {
Set<String> usernameList = new LinkedHashSet<String>();
for (GenericHumanRoleDAO role : task.getHumanRoles()) {
if (genericHumanRoleType.equals(role.getType())) {
for (OrganizationalEntityDAO orgEntity : role.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.USER.equals(orgEntity.getOrgEntityType())) {
usernameList.add(orgEntity.getName());
}
}
}
}
return usernameList;
}
/**
* Returns the list of assignable user name list.
*
* @param task : The task object.
* @param excludeActualOwner : Whether to exclude the actual owner from the returned list.
* @return : the list of assignable user name list.
*/
public static List<String> getAssignableUserNameList(TaskDAO task, boolean excludeActualOwner) {
List<String> allPotentialOwners = new ArrayList<String>();
GenericHumanRoleDAO ghr =
task.getGenericHumanRole(GenericHumanRole.GenericHumanRoleType.POTENTIAL_OWNERS);
RegistryService registryService = HumanTaskServiceComponent.getRegistryService();
for (OrganizationalEntityDAO orgEntity : ghr.getOrgEntities()) {
if (OrganizationalEntityDAO.OrganizationalEntityType.GROUP.equals(
orgEntity.getOrgEntityType())) {
String roleName = orgEntity.getName();
UserRealm userRealm;
try {
userRealm = registryService.getUserRealm(task.getTenantId());
String[] assignableUsersArray =
userRealm.getUserStoreManager().getUserListOfRole(roleName);
allPotentialOwners.addAll(Arrays.asList(assignableUsersArray));
} catch (RegistryException e) {
throw new HumanTaskRuntimeException("Cannot locate user realm for tenant id " +
task.getTenantId());
} catch (UserStoreException e) {
throw new HumanTaskRuntimeException("Error retrieving the UserStoreManager " +
task.getTenantId(), e);
}
} else if (OrganizationalEntityDAO.OrganizationalEntityType.USER.equals(
orgEntity.getOrgEntityType())) {
allPotentialOwners.add(orgEntity.getName());
}
}
OrganizationalEntityDAO actualOwner = getActualOwner(task);
if (excludeActualOwner && actualOwner != null) {
allPotentialOwners.remove(actualOwner.getName());
}
return allPotentialOwners;
}
/**
* Returns the actual owner OrganizationalEntityDAO of the given task.
*
* @param task : The task object.
* @return : The actual owner of the task IF exists, null otherwise. The caller should always
* check for null in the return value.
*/
public static OrganizationalEntityDAO getActualOwner(TaskDAO task) {
OrganizationalEntityDAO actualOwnerOrgEntity = null;
List<OrganizationalEntityDAO> actualOwner =
getOrgEntitiesForRole(task, GenericHumanRoleDAO.GenericHumanRoleType.ACTUAL_OWNER);
// There should be only 1 actual owner for the task if any exists.
if (actualOwner != null && actualOwner.size() == 1) {
actualOwnerOrgEntity = actualOwner.get(0);
}
return actualOwnerOrgEntity;
}
/**
* Creates a new TaskEventInfo object for the task creation event.
*
* @param task : The newly created task object.
*
* @return : The respective TaskEventInfo object for the task creation event.
*/
public static TaskEventInfo createNewTaskEvent(TaskDAO task) {
TaskEventInfo createTaskEvent = new TaskEventInfo();
createTaskEvent.setEventType(TaskEventType.CREATE);
createTaskEvent.setTimestamp(task.getCreatedOn());
//TODO - how to handle the event initiator for create task event ?
//createTaskEvent.setEventInitiator(null);
createTaskEvent.setTaskInfo(populateTaskInfo(task));
return createTaskEvent;
}
/**
* Creates the TaskInfo object from the provided TaskDAO object.
*
* @param taskDAO : The original task dao object
* @return : The representational TaskInfo.
*/
public static TaskInfo populateTaskInfo(TaskDAO taskDAO) {
TaskInfo taskInfo = new TaskInfo();
taskInfo.setId(taskDAO.getId());
taskInfo.setCreatedDate(taskDAO.getCreatedOn());
taskInfo.setName(taskDAO.getName());
if(getDefaultPresentationDescription(taskDAO) != null) {
taskInfo.setDescription(getDefaultPresentationDescription(taskDAO).getValue());
}
if(getActualOwner(taskDAO) != null) {
taskInfo.setOwner(getActualOwner(taskDAO).getName());
}
if(getDefaultPresentationName(taskDAO) != null) {
taskInfo.setName(getDefaultPresentationName(taskDAO).getValue());
}
if(getDefaultPresentationSubject(taskDAO) != null){
taskInfo.setSubject(getDefaultPresentationSubject(taskDAO).getValue());
}
taskInfo.setStatus(taskDAO.getStatus());
taskInfo.setType(taskDAO.getType());
taskInfo.setModifiedDate(taskDAO.getUpdatedOn());
taskInfo.setStatusBeforeSuspension(taskDAO.getStatusBeforeSuspension());
return taskInfo;
}
/**
* Create the TaskEventInfo object from the EventDAO and the TaskDAO.
* @param eventDAO : The event
* @param taskDAO : The related task dao.
*
* @return : The new TaskEventInfo object.
*/
public static TaskEventInfo populateTaskEventInfo(EventDAO eventDAO, TaskDAO taskDAO) {
TaskEventInfo eventInfo = new TaskEventInfo();
eventInfo.setTimestamp(eventDAO.getTimeStamp());
eventInfo.setEventInitiator(eventDAO.getUser());
eventInfo.setEventType(eventDAO.getType());
eventInfo.setNewState(eventDAO.getNewState());
eventInfo.setOldState(eventDAO.getOldState());
eventInfo.setTaskInfo(populateTaskInfo(taskDAO));
return eventInfo;
}
public static void addOrgEntityForUserNode(Node userNode, PeopleQueryEvaluator pqe,
List<OrganizationalEntityDAO> orgEntityList) {
String username = userNode.getTextContent();
if (username != null) {
username = username.trim();
if (username.length() > 0) {
OrganizationalEntityDAO userOrgEntityForUser = pqe.createUserOrgEntityForName(username);
orgEntityList.add(userOrgEntityForUser);
}
}
}
public static void addOrgEntityForGroupNode(Node groupNode, PeopleQueryEvaluator pqe,
List<OrganizationalEntityDAO> orgEntityList) {
String group = groupNode.getTextContent();
if (group != null) {
group = group.trim();
if (group.length() > 0) {
OrganizationalEntityDAO groupOrgEntityForRole = pqe.createGroupOrgEntityForRole(group);
orgEntityList.add(groupOrgEntityForRole);
}
}
}
public static void addOrgEntitiesForOrganizationEntityNode(Node orgEntityNode, PeopleQueryEvaluator pqe,
List<OrganizationalEntityDAO> orgEntityList) {
// Org entity node should contain either a user elements or group elements
if (orgEntityNode.getNodeType() == Node.ELEMENT_NODE) {
NodeList userList = ((Element) orgEntityNode).getElementsByTagNameNS(HumanTaskConstants.userQname.getNamespaceURI(),
HumanTaskConstants.userQname.getLocalPart());
for (int j = 0; j < userList.getLength(); j++) {
Node item = userList.item(j);
String username = item.getTextContent();
if (username != null) {
username = username.trim();
if (username.length() > 0) {
OrganizationalEntityDAO userOrgEntityForName = pqe.createUserOrgEntityForName(username);
orgEntityList.add(userOrgEntityForName);
}
}
}
NodeList groupList = ((Element) orgEntityNode).getElementsByTagNameNS(HumanTaskConstants.groupQname.getNamespaceURI(),
HumanTaskConstants.groupQname.getLocalPart());
for (int j = 0; j < groupList.getLength(); j++) {
Node item = groupList.item(j);
String groupName = item.getTextContent();
if (groupName != null) {
groupName = groupName.trim();
if (groupName.length() > 0) {
OrganizationalEntityDAO groupOrgEntityForName = pqe.createGroupOrgEntityForRole(groupName);
orgEntityList.add(groupOrgEntityForName);
}
}
}
}
}
public static void setTaskOverrideContextAttributes(TaskDAO task, Map<String, Element> headerElements) { //TODO fix this for remaining properties.
try {
if (headerElements != null) {
Element contextRequest = headerElements.get(HumanTaskConstants.HT_CONTEXT_REQUEST);
if (contextRequest != null) {
if (!TaskType.NOTIFICATION.equals(task.getType())) {
// Notification can't be skipped.
NodeList nodeList = contextRequest.getElementsByTagNameNS(
HumanTaskConstants.HT_CONTEXT_NAMESPACE, HumanTaskConstants.HT_CONTEXT_IS_SKIPABLE);
if (nodeList != null && nodeList.getLength() > 0) {
Node isSkipable = nodeList.item(0);
task.setSkipable(Boolean.parseBoolean(isSkipable.getTextContent()));
}
}
NodeList nodeList = contextRequest.getElementsByTagNameNS(
HumanTaskConstants.HT_CONTEXT_NAMESPACE, HumanTaskConstants.HT_CONTEXT_PRIORITY);
if (nodeList != null && nodeList.getLength() > 0) {
Node priority = nodeList.item(0);
task.setPriority(Integer.parseInt(priority.getTextContent()));
}
}
}
} catch (Exception e) {
log.error("Error while setting override attributes to task", e);
}
}
}