mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-21 18:09:20 +00:00
ALF-20190, ALF-20178 fixes for workflow rest api
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@56272 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -882,6 +882,7 @@
|
||||
<bean id="tasks" class="org.alfresco.rest.workflow.api.impl.TasksImpl" parent="baseWorkflowRest">
|
||||
<property name="restVariableHelper" ref="restVariableHelper" />
|
||||
<property name="messageService" ref="messageService" />
|
||||
<property name="personService" ref="PersonService" />
|
||||
</bean>
|
||||
|
||||
<bean id="Tasks" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
|
@@ -57,6 +57,7 @@ public class DeploymentsImpl extends WorkflowRestImpl implements Deployments
|
||||
|
||||
query.orderByDeploymenTime().desc();
|
||||
List<org.activiti.engine.repository.Deployment> deployments = query.listPage(paging.getSkipCount(), paging.getMaxItems());
|
||||
int totalCount = (int) query.count();
|
||||
|
||||
List<Deployment> page = new ArrayList<Deployment>(deployments.size());
|
||||
for (org.activiti.engine.repository.Deployment deployment: deployments)
|
||||
@@ -64,7 +65,7 @@ public class DeploymentsImpl extends WorkflowRestImpl implements Deployments
|
||||
page.add(new Deployment(deployment));
|
||||
}
|
||||
|
||||
return CollectionWithPagingInfo.asPaged(paging, page, false, page.size());
|
||||
return CollectionWithPagingInfo.asPaged(paging, page, page.size() != totalCount, totalCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -224,6 +224,7 @@ public class ProcessDefinitionsImpl extends WorkflowRestImpl implements ProcessD
|
||||
|
||||
List<org.activiti.engine.repository.ProcessDefinition> processDefinitions =
|
||||
query.listPage(parameters.getPaging().getSkipCount(), parameters.getPaging().getMaxItems());
|
||||
int totalCount = (int) query.count();
|
||||
|
||||
List<ProcessDefinition> page = new ArrayList<ProcessDefinition>(processDefinitions.size());
|
||||
for (org.activiti.engine.repository.ProcessDefinition processDefinition: processDefinitions)
|
||||
@@ -231,7 +232,7 @@ public class ProcessDefinitionsImpl extends WorkflowRestImpl implements ProcessD
|
||||
page.add(createProcessDefinitionRest((ProcessDefinitionEntity) processDefinition));
|
||||
}
|
||||
|
||||
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, false, page.size());
|
||||
return CollectionWithPagingInfo.asPaged(parameters.getPaging(), page, page.size() != totalCount, totalCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -607,74 +607,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
if (taskAssociations.containsKey(propNameMap.get(variableName)))
|
||||
{
|
||||
AssociationDefinition associationDef = taskAssociations.get(propNameMap.get(variableName));
|
||||
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> personList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(value.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
|
||||
}
|
||||
personList.add(personRef);
|
||||
}
|
||||
variableValue = personList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(variableValue.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
|
||||
}
|
||||
variableValue = personRef;
|
||||
}
|
||||
}
|
||||
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> authorityList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
|
||||
}
|
||||
authorityList.add(authorityRef);
|
||||
}
|
||||
variableValue = authorityList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
|
||||
}
|
||||
variableValue = authorityRef;
|
||||
}
|
||||
}
|
||||
variableValue = convertAssociationDefinitionValue(associationDef, variableName, variableValue);
|
||||
}
|
||||
else if (taskProperties.containsKey(propNameMap.get(variableName)))
|
||||
{
|
||||
@@ -921,7 +854,7 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
throw new EntityNotFoundException(processId);
|
||||
}
|
||||
|
||||
return updateVariableInProcess(processId, variable);
|
||||
return updateVariableInProcess(processId, processInstance.getProcessDefinitionId(), variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -944,21 +877,45 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
{
|
||||
for (Variable variable : variables)
|
||||
{
|
||||
updatedVariables.add(updateVariableInProcess(processId, variable));
|
||||
updatedVariables.add(updateVariableInProcess(processId, processInstance.getProcessDefinitionId(), variable));
|
||||
}
|
||||
}
|
||||
return updatedVariables;
|
||||
}
|
||||
|
||||
protected Variable updateVariableInProcess(String processId,Variable variable)
|
||||
protected Variable updateVariableInProcess(String processId, String processDefinitionId, Variable variable)
|
||||
{
|
||||
if (variable.getName() == null)
|
||||
{
|
||||
throw new InvalidArgumentException("Variable name is required.");
|
||||
}
|
||||
|
||||
// Get start-task definition for explicit typing of variables submitted at the start
|
||||
String formKey = null;
|
||||
StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(processDefinitionId);
|
||||
if (startFormData != null)
|
||||
{
|
||||
formKey = startFormData.getFormKey();
|
||||
}
|
||||
|
||||
DataTypeDefinition dataTypeDefinition = null;
|
||||
if(variable.getType() != null)
|
||||
|
||||
TypeDefinition startTaskTypeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, true);
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(startTaskTypeDefinition, getQNameConverter());
|
||||
if (context.getPropertyDefinition(variable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = context.getPropertyDefinition(variable.getName()).getDataType();
|
||||
if (variable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(variable.getType()) == false) {
|
||||
throw new InvalidArgumentException("type of variable " + variable.getName() + " should be " +
|
||||
dataTypeDefinition.getName().toPrefixString(namespaceService));
|
||||
}
|
||||
}
|
||||
else if (context.getAssociationDefinition(variable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
|
||||
}
|
||||
|
||||
if (dataTypeDefinition == null && variable.getType() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -970,13 +927,13 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
throw new InvalidArgumentException("Unsupported type of variable: '" + variable.getType() +"'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (dataTypeDefinition == null)
|
||||
{
|
||||
// Fallback to raw value when no type has been passed and not present in model
|
||||
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(variable.getValue()));
|
||||
}
|
||||
|
||||
if(dataTypeDefinition == null)
|
||||
if (dataTypeDefinition == null)
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported type of variable: '" + variable.getType() +"'.");
|
||||
}
|
||||
@@ -989,7 +946,15 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
}
|
||||
else
|
||||
{
|
||||
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, variable.getValue());
|
||||
if (context.getAssociationDefinition(variable.getName()) != null)
|
||||
{
|
||||
actualValue = convertAssociationDefinitionValue(context.getAssociationDefinition(variable.getName()),
|
||||
variable.getName(), variable.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, variable.getValue());
|
||||
}
|
||||
}
|
||||
variable.setValue(actualValue);
|
||||
|
||||
@@ -1066,6 +1031,79 @@ public class ProcessesImpl extends WorkflowRestImpl implements Processes
|
||||
}
|
||||
}
|
||||
|
||||
protected Object convertAssociationDefinitionValue(AssociationDefinition associationDef, String variableName, Object variableValue)
|
||||
{
|
||||
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> personList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(value.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
|
||||
}
|
||||
personList.add(personRef);
|
||||
}
|
||||
variableValue = personList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(variableValue.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
|
||||
}
|
||||
variableValue = personRef;
|
||||
}
|
||||
}
|
||||
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> authorityList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
|
||||
}
|
||||
authorityList.add(authorityRef);
|
||||
}
|
||||
variableValue = authorityList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
|
||||
}
|
||||
variableValue = authorityRef;
|
||||
}
|
||||
}
|
||||
return variableValue;
|
||||
}
|
||||
|
||||
protected String getProcessDefinitionKey(String paramProcessDefinitionKey)
|
||||
{
|
||||
String processDefinitionKey = null;
|
||||
|
@@ -22,7 +22,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -94,13 +93,13 @@ public class RestVariableHelper
|
||||
List<TaskVariable> result = new ArrayList<TaskVariable>();
|
||||
if (localVariables != null && localVariables.size() > 0)
|
||||
{
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(taskTypeDefinition);
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(taskTypeDefinition, getQNameConverter());
|
||||
addTaskVariables(result, localVariables, context, VariableScope.LOCAL);
|
||||
}
|
||||
|
||||
if (globalVariables != null && globalVariables.size() > 0)
|
||||
{
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(startFormTypeDefinition);
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(startFormTypeDefinition, getQNameConverter());
|
||||
addTaskVariables(result, globalVariables, context, VariableScope.GLOBAL);
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ public class RestVariableHelper
|
||||
public List<Variable> getVariables(Map<String, Object> variables, TypeDefinition typeDefinition)
|
||||
{
|
||||
List<Variable> result = new ArrayList<Variable>();
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition);
|
||||
TypeDefinitionContext context = new TypeDefinitionContext(typeDefinition, getQNameConverter());
|
||||
|
||||
Variable variable = null;
|
||||
for(Entry<String, Object> entry : variables.entrySet())
|
||||
@@ -372,40 +371,4 @@ public class RestVariableHelper
|
||||
QName type = extractTypeFromValue(value);
|
||||
return type.toPrefixString(namespaceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper contxt class used when checking variable types based on {@link TypeDefinition}.
|
||||
*
|
||||
* @author Frederik Heremans
|
||||
*/
|
||||
private class TypeDefinitionContext {
|
||||
private Map<String, PropertyDefinition> propertyDefinitions;
|
||||
private Map<String, AssociationDefinition> associationDefinitions;
|
||||
|
||||
public TypeDefinitionContext(TypeDefinition typeDefinition)
|
||||
{
|
||||
propertyDefinitions = new HashMap<String, PropertyDefinition>();
|
||||
associationDefinitions = new HashMap<String, AssociationDefinition>();
|
||||
|
||||
for (Entry<QName, PropertyDefinition> entry : typeDefinition.getProperties().entrySet())
|
||||
{
|
||||
propertyDefinitions.put(getQNameConverter().mapQNameToName(entry.getKey()), entry.getValue());
|
||||
}
|
||||
|
||||
for (Entry<QName, AssociationDefinition> entry : typeDefinition.getAssociations().entrySet())
|
||||
{
|
||||
associationDefinitions.put(getQNameConverter().mapQNameToName(entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyDefinition getPropertyDefinition(String rawVariableName)
|
||||
{
|
||||
return propertyDefinitions.get(rawVariableName);
|
||||
}
|
||||
|
||||
public AssociationDefinition getAssociationDefinition(String rawVariableName)
|
||||
{
|
||||
return associationDefinitions.get(rawVariableName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ import org.activiti.engine.task.DelegationState;
|
||||
import org.activiti.engine.task.IdentityLink;
|
||||
import org.activiti.engine.task.IdentityLinkType;
|
||||
import org.activiti.engine.task.TaskQuery;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.i18n.MessageService;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
@@ -65,10 +66,11 @@ import org.alfresco.rest.workflow.api.model.TaskVariable;
|
||||
import org.alfresco.rest.workflow.api.model.VariableScope;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.InvalidQNameException;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ISO8601DateFormat;
|
||||
@@ -123,6 +125,7 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
private WorkflowObjectFactory workflowFactory;
|
||||
private WorkflowQNameConverter qNameConverter;
|
||||
private MessageService messageService;
|
||||
private PersonService personService;
|
||||
|
||||
public void setRestVariableHelper(RestVariableHelper restVariableHelper)
|
||||
{
|
||||
@@ -134,6 +137,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
this.messageService = messageService;
|
||||
}
|
||||
|
||||
public void setPersonService(PersonService personService)
|
||||
{
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Task> getTasks(Parameters parameters)
|
||||
{
|
||||
@@ -1054,9 +1062,63 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
{
|
||||
throw new InvalidArgumentException("Variable scope is required and can only be 'local' or 'global'.");
|
||||
}
|
||||
|
||||
|
||||
DataTypeDefinition dataTypeDefinition = null;
|
||||
if (taskVariable.getType() != null)
|
||||
TypeDefinitionContext context = null;
|
||||
if (taskVariable.getVariableScope() == VariableScope.GLOBAL)
|
||||
{
|
||||
// Get start-task definition for explicit typing of variables submitted at the start
|
||||
String formKey = null;
|
||||
StartFormData startFormData = activitiProcessEngine.getFormService().getStartFormData(taskInstance.getProcessDefinitionId());
|
||||
if (startFormData != null)
|
||||
{
|
||||
formKey = startFormData.getFormKey();
|
||||
}
|
||||
|
||||
TypeDefinition startTaskTypeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, true);
|
||||
context = new TypeDefinitionContext(startTaskTypeDefinition, getQNameConverter());
|
||||
if (context.getPropertyDefinition(taskVariable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = context.getPropertyDefinition(taskVariable.getName()).getDataType();
|
||||
if (taskVariable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(taskVariable.getType()) == false) {
|
||||
throw new InvalidArgumentException("type of variable " + taskVariable.getName() + " should be " +
|
||||
dataTypeDefinition.getName().toPrefixString(namespaceService));
|
||||
}
|
||||
}
|
||||
else if (context.getAssociationDefinition(taskVariable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Revert to either the content-model type or the raw type provided by the request
|
||||
try
|
||||
{
|
||||
String formKey = activitiProcessEngine.getFormService().getTaskFormKey(taskInstance.getProcessDefinitionId(), taskInstance.getTaskDefinitionKey());
|
||||
TypeDefinition typeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, false);
|
||||
context = new TypeDefinitionContext(typeDefinition, getQNameConverter());
|
||||
if (context.getPropertyDefinition(taskVariable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = context.getPropertyDefinition(taskVariable.getName()).getDataType();
|
||||
if (taskVariable.getType() != null && dataTypeDefinition.getName().toPrefixString(namespaceService).equals(taskVariable.getType()) == false) {
|
||||
throw new InvalidArgumentException("type of variable " + taskVariable.getName() + " should be " +
|
||||
dataTypeDefinition.getName().toPrefixString(namespaceService));
|
||||
}
|
||||
}
|
||||
else if (context.getAssociationDefinition(taskVariable.getName()) != null)
|
||||
{
|
||||
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
|
||||
}
|
||||
}
|
||||
catch (InvalidQNameException ignore)
|
||||
{
|
||||
// In case the property is not part of the model, it's possible that the property-name is not a valid.
|
||||
// This can be ignored safeley as it falls back to the raw type
|
||||
}
|
||||
}
|
||||
|
||||
if (dataTypeDefinition == null && taskVariable.getType() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1067,41 +1129,11 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
{
|
||||
throw new InvalidArgumentException("Unsupported type of variable: '" + taskVariable.getType() +"'.");
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else if (dataTypeDefinition == null)
|
||||
{
|
||||
// Revert to either the content-model type or the raw type provided by the request
|
||||
try
|
||||
{
|
||||
String formKey = activitiProcessEngine.getFormService().getTaskFormKey(taskInstance.getProcessDefinitionId(), taskInstance.getTaskDefinitionKey());
|
||||
TypeDefinition typeDefinition = getWorkflowFactory().getTaskFullTypeDefinition(formKey, false);
|
||||
QName propQName = WorkflowQNameConverter.convertNameToQName(taskVariable.getName(), namespaceService);
|
||||
|
||||
PropertyDefinition propDef = typeDefinition.getProperties().get(propQName);
|
||||
if (propDef != null)
|
||||
{
|
||||
dataTypeDefinition = propDef.getDataType();
|
||||
}
|
||||
else
|
||||
{
|
||||
AssociationDefinition assocDef = typeDefinition.getAssociations().get(propQName);
|
||||
if(assocDef != null)
|
||||
{
|
||||
dataTypeDefinition = dictionaryService.getDataType(DataTypeDefinition.NODE_REF);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvalidQNameException ignore)
|
||||
{
|
||||
// In case the property is not part of the model, it's possible that the property-name is not a valid.
|
||||
// This can be ignored safeley as it falls back to the raw type
|
||||
}
|
||||
|
||||
if (dataTypeDefinition == null)
|
||||
{
|
||||
// Final fallback to raw value when no type has been passed and not present in model
|
||||
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue()));
|
||||
}
|
||||
// Final fallback to raw value when no type has been passed and not present in model
|
||||
dataTypeDefinition = dictionaryService.getDataType(restVariableHelper.extractTypeFromValue(taskVariable.getValue()));
|
||||
}
|
||||
|
||||
if (dataTypeDefinition == null)
|
||||
@@ -1117,7 +1149,15 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
}
|
||||
else
|
||||
{
|
||||
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, taskVariable.getValue());
|
||||
if (context != null && context.getAssociationDefinition(taskVariable.getName()) != null)
|
||||
{
|
||||
actualValue = convertAssociationDefinitionValue(context.getAssociationDefinition(taskVariable.getName()),
|
||||
taskVariable.getName(), taskVariable.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
actualValue = DefaultTypeConverter.INSTANCE.convert(dataTypeDefinition, taskVariable.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
taskVariable.setValue(actualValue);
|
||||
@@ -1556,6 +1596,92 @@ public class TasksImpl extends WorkflowRestImpl implements Tasks
|
||||
}
|
||||
}
|
||||
|
||||
protected Object convertAssociationDefinitionValue(AssociationDefinition associationDef, String variableName, Object variableValue)
|
||||
{
|
||||
if (variableValue != null && ContentModel.TYPE_PERSON.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> personList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(value.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid person user id");
|
||||
}
|
||||
personList.add(personRef);
|
||||
}
|
||||
variableValue = personList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef personRef = getPersonNodeRef(variableValue.toString());
|
||||
if (personRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid person user id");
|
||||
}
|
||||
variableValue = personRef;
|
||||
}
|
||||
}
|
||||
else if (variableValue != null && ContentModel.TYPE_AUTHORITY_CONTAINER.equals(associationDef.getTargetClass().getName()))
|
||||
{
|
||||
if (associationDef.isTargetMany())
|
||||
{
|
||||
if (variableValue instanceof List<?>)
|
||||
{
|
||||
List<NodeRef> authorityList = new ArrayList<NodeRef>();
|
||||
List<?> values = (List<?>) variableValue;
|
||||
for (Object value : values)
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(value.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(value.toString() + " is not a valid authority id");
|
||||
}
|
||||
authorityList.add(authorityRef);
|
||||
}
|
||||
variableValue = authorityList;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidArgumentException(variableName + " should have an array value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NodeRef authorityRef = authorityService.getAuthorityNodeRef(variableValue.toString());
|
||||
if (authorityRef == null)
|
||||
{
|
||||
throw new InvalidArgumentException(variableValue.toString() + " is not a valid authority id");
|
||||
}
|
||||
variableValue = authorityRef;
|
||||
}
|
||||
}
|
||||
return variableValue;
|
||||
}
|
||||
|
||||
protected NodeRef getPersonNodeRef(String name)
|
||||
{
|
||||
NodeRef authority = null;
|
||||
if (name != null)
|
||||
{
|
||||
if (personService.personExists(name))
|
||||
{
|
||||
authority = personService.getPerson(name);
|
||||
}
|
||||
}
|
||||
return authority;
|
||||
}
|
||||
|
||||
protected WorkflowQNameConverter getQNameConverter()
|
||||
{
|
||||
if (qNameConverter == null)
|
||||
|
@@ -0,0 +1,48 @@
|
||||
package org.alfresco.rest.workflow.api.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.alfresco.repo.workflow.WorkflowQNameConverter;
|
||||
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Helper contxt class used when checking variable types based on {@link TypeDefinition}.
|
||||
*
|
||||
* @author Frederik Heremans
|
||||
*/
|
||||
public class TypeDefinitionContext {
|
||||
|
||||
private Map<String, PropertyDefinition> propertyDefinitions;
|
||||
private Map<String, AssociationDefinition> associationDefinitions;
|
||||
|
||||
public TypeDefinitionContext(TypeDefinition typeDefinition, WorkflowQNameConverter qNameConverter)
|
||||
{
|
||||
propertyDefinitions = new HashMap<String, PropertyDefinition>();
|
||||
associationDefinitions = new HashMap<String, AssociationDefinition>();
|
||||
|
||||
for (Entry<QName, PropertyDefinition> entry : typeDefinition.getProperties().entrySet())
|
||||
{
|
||||
propertyDefinitions.put(qNameConverter.mapQNameToName(entry.getKey()), entry.getValue());
|
||||
}
|
||||
|
||||
for (Entry<QName, AssociationDefinition> entry : typeDefinition.getAssociations().entrySet())
|
||||
{
|
||||
associationDefinitions.put(qNameConverter.mapQNameToName(entry.getKey()), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyDefinition getPropertyDefinition(String rawVariableName)
|
||||
{
|
||||
return propertyDefinitions.get(rawVariableName);
|
||||
}
|
||||
|
||||
public AssociationDefinition getAssociationDefinition(String rawVariableName)
|
||||
{
|
||||
return associationDefinitions.get(rawVariableName);
|
||||
}
|
||||
}
|
@@ -38,6 +38,7 @@ import org.alfresco.rest.api.tests.client.PublicApiException;
|
||||
import org.alfresco.rest.api.tests.client.RequestContext;
|
||||
import org.alfresco.rest.workflow.api.model.Deployment;
|
||||
import org.alfresco.rest.workflow.api.tests.WorkflowApiClient.DeploymentsClient;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
@@ -120,6 +121,58 @@ public class DeploymentWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
assertEquals(activitiDeployment.getCategory(), adhocDeployment.getCategory());
|
||||
assertEquals(activitiDeployment.getName(), adhocDeployment.getName());
|
||||
assertEquals(activitiDeployment.getDeploymentTime(), adhocDeployment.getDeployedAt());
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("maxItems", "2");
|
||||
JSONObject deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
|
||||
assertNotNull(deploymentsListObject);
|
||||
JSONObject paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
|
||||
assertEquals(2l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
|
||||
assertNotNull(deploymentsListObject);
|
||||
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
|
||||
assertEquals(5l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(false, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "2");
|
||||
params.put("maxItems", "2");
|
||||
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
|
||||
assertNotNull(deploymentsListObject);
|
||||
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
|
||||
assertEquals(2l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(2l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "2");
|
||||
params.put("maxItems", "5");
|
||||
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
|
||||
assertNotNull(deploymentsListObject);
|
||||
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
|
||||
assertEquals(3l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(2l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "0");
|
||||
params.put("maxItems", "7");
|
||||
deploymentsListObject = deploymentsClient.getDeploymentsWithRawResponse(params);
|
||||
assertNotNull(deploymentsListObject);
|
||||
paginationJSON = (JSONObject) deploymentsListObject.get("pagination");
|
||||
assertEquals(5l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(false, paginationJSON.get("hasMoreItems"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -88,6 +88,58 @@ public class ProcessDefinitionWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
assertEquals("wf:submitAdhocTask", adhocDefinitionRest.getStartFormResourceKey());
|
||||
assertEquals("New Task", adhocDefinitionRest.getTitle());
|
||||
assertEquals("Assign a new task to yourself or a colleague", adhocDefinitionRest.getDescription());
|
||||
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("maxItems", "2");
|
||||
JSONObject definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
|
||||
assertNotNull(definitionListObject);
|
||||
JSONObject paginationJSON = (JSONObject) definitionListObject.get("pagination");
|
||||
assertEquals(2l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
|
||||
assertNotNull(definitionListObject);
|
||||
paginationJSON = (JSONObject) definitionListObject.get("pagination");
|
||||
assertEquals(5l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(false, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "2");
|
||||
params.put("maxItems", "2");
|
||||
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
|
||||
assertNotNull(definitionListObject);
|
||||
paginationJSON = (JSONObject) definitionListObject.get("pagination");
|
||||
assertEquals(2l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(2l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "2");
|
||||
params.put("maxItems", "5");
|
||||
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
|
||||
assertNotNull(definitionListObject);
|
||||
paginationJSON = (JSONObject) definitionListObject.get("pagination");
|
||||
assertEquals(3l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(2l, paginationJSON.get("skipCount"));
|
||||
assertEquals(true, paginationJSON.get("hasMoreItems"));
|
||||
|
||||
params = new HashMap<String, String>();
|
||||
params.put("skipCount", "0");
|
||||
params.put("maxItems", "7");
|
||||
definitionListObject = processDefinitionsClient.getProcessDefinitionsWithRawResponse(params);
|
||||
assertNotNull(definitionListObject);
|
||||
paginationJSON = (JSONObject) definitionListObject.get("pagination");
|
||||
assertEquals(5l, paginationJSON.get("count"));
|
||||
assertEquals(5l, paginationJSON.get("totalItems"));
|
||||
assertEquals(0l, paginationJSON.get("skipCount"));
|
||||
assertEquals(false, paginationJSON.get("hasMoreItems"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -1749,6 +1749,25 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
assertEquals("d:long", result.get("type"));
|
||||
assertEquals(4567L, activitiProcessEngine.getRuntimeService().getVariable(processId, "newVariable"));
|
||||
|
||||
JSONObject processvariables = publicApiClient.processesClient().getProcessvariables(processId);
|
||||
assertNotNull(processvariables);
|
||||
JSONObject newVariableEntry = null;
|
||||
JSONArray entries = (JSONArray) processvariables.get("entries");
|
||||
assertNotNull(entries);
|
||||
for(int i=0; i<entries.size(); i++)
|
||||
{
|
||||
JSONObject entry = (JSONObject) entries.get(i);
|
||||
assertNotNull(entry);
|
||||
entry = (JSONObject) entry.get("entry");
|
||||
assertNotNull(entry);
|
||||
if ("newVariable".equals((String) entry.get("name"))) {
|
||||
newVariableEntry = entry;
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(newVariableEntry);
|
||||
assertEquals(4567L, newVariableEntry.get("value"));
|
||||
|
||||
// Update an existing variable, creates a new one using no explicit typing
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "stringVariable");
|
||||
@@ -1856,6 +1875,187 @@ public class ProcessWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testUpdateProcessVariableWithWrongType() throws Exception
|
||||
{
|
||||
final RequestContext requestContext = initApiClientWithTestUser();
|
||||
|
||||
ProcessInfo processRest = startParallelReviewProcess(requestContext);
|
||||
|
||||
try
|
||||
{
|
||||
assertNotNull(processRest);
|
||||
String processId = processRest.getId();
|
||||
|
||||
// Update an existing variable with wrong type
|
||||
JSONObject variableJson = new JSONObject();
|
||||
variableJson.put("name", "wf_requiredApprovePercent");
|
||||
variableJson.put("value", 55.99);
|
||||
variableJson.put("type", "d:double");
|
||||
|
||||
try
|
||||
{
|
||||
publicApiClient.processesClient().updateVariable(processId, "wf_requiredApprovePercent", variableJson);
|
||||
fail("Exception expected");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "wf_requiredApprovePercent");
|
||||
variableJson.put("value", 55.99);
|
||||
variableJson.put("type", "d:int");
|
||||
|
||||
JSONObject resultEntry = publicApiClient.processesClient().updateVariable(processId, "wf_requiredApprovePercent", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
JSONObject result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("wf_requiredApprovePercent", result.get("name"));
|
||||
assertEquals(55l, result.get("value"));
|
||||
assertEquals("d:int", result.get("type"));
|
||||
assertEquals(55, activitiProcessEngine.getRuntimeService().getVariable(processId, "wf_requiredApprovePercent"));
|
||||
|
||||
JSONObject processvariables = publicApiClient.processesClient().getProcessvariables(processId);
|
||||
assertNotNull(processvariables);
|
||||
|
||||
// Add process variables to map for easy lookup
|
||||
Map<String, JSONObject> variablesByName = new HashMap<String, JSONObject>();
|
||||
JSONObject entry = null;
|
||||
JSONArray entries = (JSONArray) processvariables.get("entries");
|
||||
assertNotNull(entries);
|
||||
for(int i=0; i<entries.size(); i++)
|
||||
{
|
||||
entry = (JSONObject) entries.get(i);
|
||||
assertNotNull(entry);
|
||||
entry = (JSONObject) entry.get("entry");
|
||||
assertNotNull(entry);
|
||||
variablesByName.put((String) entry.get("name"), entry);
|
||||
}
|
||||
|
||||
JSONObject approvePercentObject = variablesByName.get("wf_requiredApprovePercent");
|
||||
assertNotNull(approvePercentObject);
|
||||
assertEquals(55l, approvePercentObject.get("value"));
|
||||
assertEquals("d:int", approvePercentObject.get("type"));
|
||||
|
||||
// set a new variable
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "testVariable");
|
||||
variableJson.put("value", "text");
|
||||
variableJson.put("type", "d:text");
|
||||
|
||||
resultEntry = publicApiClient.processesClient().updateVariable(processId, "testVariable", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("testVariable", result.get("name"));
|
||||
assertEquals("text", result.get("value"));
|
||||
assertEquals("d:text", result.get("type"));
|
||||
assertEquals("text", activitiProcessEngine.getRuntimeService().getVariable(processId, "testVariable"));
|
||||
|
||||
// change the variable value and type (should be working because no content model type)
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "testVariable");
|
||||
variableJson.put("value", 123);
|
||||
variableJson.put("type", "d:int");
|
||||
|
||||
resultEntry = publicApiClient.processesClient().updateVariable(processId, "testVariable", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("testVariable", result.get("name"));
|
||||
assertEquals(123l, result.get("value"));
|
||||
assertEquals("d:int", result.get("type"));
|
||||
assertEquals(123, activitiProcessEngine.getRuntimeService().getVariable(processId, "testVariable"));
|
||||
|
||||
// change the variable value for a list of noderefs (bpm_assignees)
|
||||
final JSONObject updateAssigneesJson = new JSONObject();
|
||||
updateAssigneesJson.put("name", "bpm_assignees");
|
||||
updateAssigneesJson.put("type", "d:noderef");
|
||||
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
JSONArray assigneeArray = new JSONArray();
|
||||
assigneeArray.add(requestContext.getRunAsUser());
|
||||
updateAssigneesJson.put("value", assigneeArray);
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
resultEntry = publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", updateAssigneesJson);
|
||||
assertNotNull(resultEntry);
|
||||
final JSONObject updateAssigneeResult = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("bpm_assignees", updateAssigneeResult.get("name"));
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
JSONArray assigneeArray = (JSONArray) updateAssigneeResult.get("value");
|
||||
assertNotNull(assigneeArray);
|
||||
assertEquals(1, assigneeArray.size());
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
assertEquals("d:noderef", updateAssigneeResult.get("type"));
|
||||
|
||||
// update the bpm_assignees with a single entry, should result in an error
|
||||
final JSONObject updateAssigneeJson = new JSONObject();
|
||||
updateAssigneeJson.put("name", "bpm_assignees");
|
||||
updateAssigneeJson.put("type", "d:noderef");
|
||||
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
updateAssigneeJson.put("value", requestContext.getRunAsUser());
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
try
|
||||
{
|
||||
publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", updateAssigneeJson);
|
||||
fail("Exception expected");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
// change the variable value with a non-existing person
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "bpm_assignees");
|
||||
JSONArray assigneeArray = new JSONArray();
|
||||
assigneeArray.add("nonExistingPerson");
|
||||
variableJson.put("value", assigneeArray);
|
||||
variableJson.put("type", "d:noderef");
|
||||
|
||||
try
|
||||
{
|
||||
publicApiClient.processesClient().updateVariable(processId, "bpm_assignees", variableJson);
|
||||
fail("Exception expected");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
cleanupProcessInstance(processRest.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteProcessVariable() throws Exception
|
||||
{
|
||||
|
@@ -1106,7 +1106,7 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
JSONObject variableBody = new JSONObject();
|
||||
variableBody.put("name", "bpm_workflowDueDate");
|
||||
variableBody.put("value", formatDate(new Date()));
|
||||
variableBody.put("type", "d:datetime");
|
||||
variableBody.put("type", "d:date");
|
||||
variableBody.put("scope", "global");
|
||||
|
||||
tasksClient.updateTaskVariable(task.getId(), "bpm_workflowDueDate", variableBody);
|
||||
@@ -2397,6 +2397,179 @@ public class TaskWorkflowApiTest extends EnterpriseWorkflowTestApi
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testUpdateTaskVariableWithWrongType() throws Exception
|
||||
{
|
||||
final RequestContext requestContext = initApiClientWithTestUser();
|
||||
|
||||
ProcessInfo processRest = startParallelReviewProcess(requestContext);
|
||||
|
||||
try
|
||||
{
|
||||
List<Task> tasks = activitiProcessEngine.getTaskService().createTaskQuery().processInstanceId(processRest.getId()).list();
|
||||
assertNotNull(tasks);
|
||||
|
||||
String taskId = tasks.get(0).getId();
|
||||
|
||||
// Update an existing variable with wrong type
|
||||
JSONObject variableJson = new JSONObject();
|
||||
variableJson.put("name", "wf_requiredApprovePercent");
|
||||
variableJson.put("value", 55.99);
|
||||
variableJson.put("type", "d:double");
|
||||
variableJson.put("scope", "global");
|
||||
|
||||
try
|
||||
{
|
||||
publicApiClient.tasksClient().updateTaskVariable(taskId, "wf_requiredApprovePercent", variableJson);
|
||||
fail("Exception expected");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "wf_requiredApprovePercent");
|
||||
variableJson.put("value", 55.99);
|
||||
variableJson.put("type", "d:int");
|
||||
variableJson.put("scope", "global");
|
||||
|
||||
JSONObject resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "wf_requiredApprovePercent", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
JSONObject result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("wf_requiredApprovePercent", result.get("name"));
|
||||
assertEquals(55l, result.get("value"));
|
||||
assertEquals("d:int", result.get("type"));
|
||||
assertEquals(55, activitiProcessEngine.getRuntimeService().getVariable(processRest.getId(), "wf_requiredApprovePercent"));
|
||||
|
||||
JSONObject taskVariables = publicApiClient.tasksClient().findTaskVariables(taskId);
|
||||
assertNotNull(taskVariables);
|
||||
JSONObject list = (JSONObject) taskVariables.get("list");
|
||||
assertNotNull(list);
|
||||
|
||||
// Add process variables to map for easy lookup
|
||||
Map<String, JSONObject> variablesByName = new HashMap<String, JSONObject>();
|
||||
JSONObject entry = null;
|
||||
JSONArray entries = (JSONArray) list.get("entries");
|
||||
assertNotNull(entries);
|
||||
for(int i=0; i<entries.size(); i++)
|
||||
{
|
||||
entry = (JSONObject) entries.get(i);
|
||||
assertNotNull(entry);
|
||||
entry = (JSONObject) entry.get("entry");
|
||||
assertNotNull(entry);
|
||||
variablesByName.put((String) entry.get("name"), entry);
|
||||
}
|
||||
|
||||
JSONObject approvePercentObject = variablesByName.get("wf_requiredApprovePercent");
|
||||
assertNotNull(approvePercentObject);
|
||||
assertEquals(55l, approvePercentObject.get("value"));
|
||||
assertEquals("d:int", approvePercentObject.get("type"));
|
||||
|
||||
// set a new variable
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "testVariable");
|
||||
variableJson.put("value", "text");
|
||||
variableJson.put("type", "d:text");
|
||||
variableJson.put("scope", "local");
|
||||
|
||||
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "testVariable", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("testVariable", result.get("name"));
|
||||
assertEquals("text", result.get("value"));
|
||||
assertEquals("d:text", result.get("type"));
|
||||
assertEquals("text", activitiProcessEngine.getTaskService().getVariable(taskId, "testVariable"));
|
||||
|
||||
// change the variable value and type (should be working because no content model type)
|
||||
variableJson = new JSONObject();
|
||||
variableJson.put("name", "testVariable");
|
||||
variableJson.put("value", 123);
|
||||
variableJson.put("type", "d:int");
|
||||
variableJson.put("scope", "local");
|
||||
|
||||
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "testVariable", variableJson);
|
||||
assertNotNull(resultEntry);
|
||||
result = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("testVariable", result.get("name"));
|
||||
assertEquals(123l, result.get("value"));
|
||||
assertEquals("d:int", result.get("type"));
|
||||
assertEquals(123, activitiProcessEngine.getTaskService().getVariable(taskId, "testVariable"));
|
||||
|
||||
// change the variable value for a list of noderefs (bpm_assignees)
|
||||
final JSONObject updateAssigneesJson = new JSONObject();
|
||||
updateAssigneesJson.put("name", "bpm_assignees");
|
||||
updateAssigneesJson.put("type", "d:noderef");
|
||||
updateAssigneesJson.put("scope", "global");
|
||||
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
JSONArray assigneeArray = new JSONArray();
|
||||
assigneeArray.add(requestContext.getRunAsUser());
|
||||
updateAssigneesJson.put("value", assigneeArray);
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
resultEntry = publicApiClient.tasksClient().updateTaskVariable(taskId, "bpm_assignees", updateAssigneesJson);
|
||||
assertNotNull(resultEntry);
|
||||
final JSONObject updateAssigneeResult = (JSONObject) resultEntry.get("entry");
|
||||
|
||||
assertEquals("bpm_assignees", updateAssigneeResult.get("name"));
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
JSONArray assigneeArray = (JSONArray) updateAssigneeResult.get("value");
|
||||
assertNotNull(assigneeArray);
|
||||
assertEquals(1, assigneeArray.size());
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
assertEquals("d:noderef", updateAssigneeResult.get("type"));
|
||||
|
||||
// update the bpm_assignees with a single entry, should result in an error
|
||||
final JSONObject updateAssigneeJson = new JSONObject();
|
||||
updateAssigneeJson.put("name", "bpm_assignees");
|
||||
updateAssigneeJson.put("type", "d:noderef");
|
||||
updateAssigneeJson.put("scope", "global");
|
||||
|
||||
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
updateAssigneeJson.put("value", requestContext.getRunAsUser());
|
||||
return null;
|
||||
}
|
||||
}, requestContext.getRunAsUser(), requestContext.getNetworkId());
|
||||
|
||||
try
|
||||
{
|
||||
publicApiClient.tasksClient().updateTaskVariable(taskId, "bpm_assignees", updateAssigneeJson);
|
||||
fail("Exception expected");
|
||||
}
|
||||
catch (PublicApiException e)
|
||||
{
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpResponse().getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
cleanupProcessInstance(processRest.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUpdateTaskVariablesAuthentication() throws Exception
|
||||
|
@@ -69,6 +69,13 @@ public class WorkflowApiClient extends PublicApiClient
|
||||
HttpResponse response = getAll("deployments", null, null, null, params, "Failed to get deploymentsClient");
|
||||
return DeploymentParser.INSTANCE.parseList(response.getJsonResponse());
|
||||
}
|
||||
|
||||
public JSONObject getDeploymentsWithRawResponse(Map<String, String> params) throws PublicApiException
|
||||
{
|
||||
HttpResponse response = getAll("deployments", null, null, null, params, "Failed to get deploymentsClient");
|
||||
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
|
||||
return list;
|
||||
}
|
||||
|
||||
public ListResponse<Deployment> getDeployments() throws PublicApiException
|
||||
{
|
||||
@@ -106,6 +113,13 @@ public class WorkflowApiClient extends PublicApiClient
|
||||
HttpResponse response = getAll("process-definitions", null, null, null, params, "Failed to get process definitions");
|
||||
return ProcessDefinitionParser.INSTANCE.parseList(response.getJsonResponse());
|
||||
}
|
||||
|
||||
public JSONObject getProcessDefinitionsWithRawResponse(Map<String, String> params) throws PublicApiException
|
||||
{
|
||||
HttpResponse response = getAll("process-definitions", null, null, null, params, "Failed to get process definitions");
|
||||
JSONObject list = (JSONObject) response.getJsonResponse().get("list");
|
||||
return list;
|
||||
}
|
||||
|
||||
public ProcessDefinition findProcessDefinitionById(String processDefinitionId) throws PublicApiException
|
||||
{
|
||||
|
Reference in New Issue
Block a user