提交 0946782d 编写于 作者: J Joram Barrez

Merge branch 'master' of https://github.com/Activiti/Activiti

......@@ -30,6 +30,7 @@ import org.activiti.bpmn.model.Artifact;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.Event;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.ExtensionAttribute;
import org.activiti.bpmn.model.ExtensionElement;
......@@ -39,10 +40,12 @@ import org.activiti.bpmn.model.FormValue;
import org.activiti.bpmn.model.Gateway;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.TerminateEventDefinition;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.UserTask;
import org.apache.commons.lang3.StringUtils;
......@@ -151,12 +154,22 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
if (activity.isNotExclusive()) {
writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
}
writeDefaultAttribute(ATTRIBUTE_DEFAULT, activity.getDefaultFlow(), xtw);
if (StringUtils.isNotEmpty(activity.getDefaultFlow())) {
FlowElement defaultFlowElement = model.getFlowElement(activity.getDefaultFlow());
if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
writeDefaultAttribute(ATTRIBUTE_DEFAULT, activity.getDefaultFlow(), xtw);
}
}
}
if (baseElement instanceof Gateway) {
final Gateway gateway = (Gateway) baseElement;
writeDefaultAttribute(ATTRIBUTE_DEFAULT, gateway.getDefaultFlow(), xtw);
if (StringUtils.isNotEmpty(gateway.getDefaultFlow())) {
FlowElement defaultFlowElement = model.getFlowElement(gateway.getDefaultFlow());
if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
writeDefaultAttribute(ATTRIBUTE_DEFAULT, gateway.getDefaultFlow(), xtw);
}
}
}
writeAdditionalAttributes(baseElement, xtw);
......@@ -342,23 +355,23 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
return ActivitiListenerExport.writeListeners(element, didWriteExtensionStartElement, xtw);
}
protected void writeEventDefinitions(List<EventDefinition> eventDefinitions, XMLStreamWriter xtw) throws Exception {
protected void writeEventDefinitions(Event parentEvent, List<EventDefinition> eventDefinitions, XMLStreamWriter xtw) throws Exception {
for (EventDefinition eventDefinition : eventDefinitions) {
if (eventDefinition instanceof TimerEventDefinition) {
writeTimerDefinition((TimerEventDefinition) eventDefinition, xtw);
writeTimerDefinition(parentEvent, (TimerEventDefinition) eventDefinition, xtw);
} else if (eventDefinition instanceof SignalEventDefinition) {
writeSignalDefinition((SignalEventDefinition) eventDefinition, xtw);
writeSignalDefinition(parentEvent, (SignalEventDefinition) eventDefinition, xtw);
} else if (eventDefinition instanceof MessageEventDefinition) {
writeMessageDefinition((MessageEventDefinition) eventDefinition, xtw);
writeMessageDefinition(parentEvent, (MessageEventDefinition) eventDefinition, xtw);
} else if (eventDefinition instanceof ErrorEventDefinition) {
writeErrorDefinition((ErrorEventDefinition) eventDefinition, xtw);
writeErrorDefinition(parentEvent, (ErrorEventDefinition) eventDefinition, xtw);
} else if (eventDefinition instanceof TerminateEventDefinition) {
writeTerminateDefinition((TerminateEventDefinition) eventDefinition, xtw);
writeTerminateDefinition(parentEvent, (TerminateEventDefinition) eventDefinition, xtw);
}
}
}
protected void writeTimerDefinition(TimerEventDefinition timerDefinition, XMLStreamWriter xtw) throws Exception {
protected void writeTimerDefinition(Event parentEvent, TimerEventDefinition timerDefinition, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(ELEMENT_EVENT_TIMERDEFINITION);
boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(timerDefinition, false, xtw);
if (didWriteExtensionStartElement) {
......@@ -383,9 +396,12 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
xtw.writeEndElement();
}
protected void writeSignalDefinition(SignalEventDefinition signalDefinition, XMLStreamWriter xtw) throws Exception {
protected void writeSignalDefinition(Event parentEvent, SignalEventDefinition signalDefinition, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(ELEMENT_EVENT_SIGNALDEFINITION);
writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw);
if (parentEvent instanceof ThrowEvent && signalDefinition.isAsync()) {
BpmnXMLUtil.writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, "true", xtw);
}
boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(signalDefinition, false, xtw);
if (didWriteExtensionStartElement) {
xtw.writeEndElement();
......@@ -393,7 +409,7 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
xtw.writeEndElement();
}
protected void writeMessageDefinition(MessageEventDefinition messageDefinition, XMLStreamWriter xtw) throws Exception {
protected void writeMessageDefinition(Event parentEvent, MessageEventDefinition messageDefinition, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(ELEMENT_EVENT_MESSAGEDEFINITION);
String messageRef = messageDefinition.getMessageRef();
......@@ -420,7 +436,7 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
xtw.writeEndElement();
}
protected void writeErrorDefinition(ErrorEventDefinition errorDefinition, XMLStreamWriter xtw) throws Exception {
protected void writeErrorDefinition(Event parentEvent, ErrorEventDefinition errorDefinition, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(ELEMENT_EVENT_ERRORDEFINITION);
writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw);
boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(errorDefinition, false, xtw);
......@@ -430,7 +446,7 @@ public abstract class BaseBpmnXMLConverter implements BpmnXMLConstants {
xtw.writeEndElement();
}
protected void writeTerminateDefinition(TerminateEventDefinition terminateDefinition, XMLStreamWriter xtw) throws Exception {
protected void writeTerminateDefinition(Event parentEvent, TerminateEventDefinition terminateDefinition, XMLStreamWriter xtw) throws Exception {
xtw.writeStartElement(ELEMENT_EVENT_TERMINATEDEFINITION);
boolean didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(terminateDefinition, false, xtw);
if (didWriteExtensionStartElement) {
......
......@@ -88,6 +88,6 @@ public class BoundaryEventXMLConverter extends BaseBpmnXMLConverter {
@Override
protected void writeAdditionalChildElements(BaseElement element, XMLStreamWriter xtw) throws Exception {
BoundaryEvent boundaryEvent = (BoundaryEvent) element;
writeEventDefinitions(boundaryEvent.getEventDefinitions(), xtw);
writeEventDefinitions(boundaryEvent, boundaryEvent.getEventDefinitions(), xtw);
}
}
......@@ -57,6 +57,6 @@ public class CatchEventXMLConverter extends BaseBpmnXMLConverter {
@Override
protected void writeAdditionalChildElements(BaseElement element, XMLStreamWriter xtw) throws Exception {
IntermediateCatchEvent catchEvent = (IntermediateCatchEvent) element;
writeEventDefinitions(catchEvent.getEventDefinitions(), xtw);
writeEventDefinitions(catchEvent, catchEvent.getEventDefinitions(), xtw);
}
}
......@@ -56,6 +56,6 @@ public class EndEventXMLConverter extends BaseBpmnXMLConverter {
@Override
protected void writeAdditionalChildElements(BaseElement element, XMLStreamWriter xtw) throws Exception {
EndEvent endEvent = (EndEvent) element;
writeEventDefinitions(endEvent.getEventDefinitions(), xtw);
writeEventDefinitions(endEvent, endEvent.getEventDefinitions(), xtw);
}
}
......@@ -81,7 +81,7 @@ public class StartEventXMLConverter extends BaseBpmnXMLConverter {
@Override
protected void writeAdditionalChildElements(BaseElement element, XMLStreamWriter xtw) throws Exception {
StartEvent startEvent = (StartEvent) element;
writeEventDefinitions(startEvent.getEventDefinitions(), xtw);
writeEventDefinitions(startEvent, startEvent.getEventDefinitions(), xtw);
}
public void addFormType(String formType) {
......
......@@ -56,6 +56,6 @@ public class ThrowEventXMLConverter extends BaseBpmnXMLConverter {
@Override
protected void writeAdditionalChildElements(BaseElement element, XMLStreamWriter xtw) throws Exception {
ThrowEvent throwEvent = (ThrowEvent) element;
writeEventDefinitions(throwEvent.getEventDefinitions(), xtw);
writeEventDefinitions(throwEvent, throwEvent.getEventDefinitions(), xtw);
}
}
......@@ -41,19 +41,5 @@ public abstract class FlowNode extends FlowElement {
public void setValues(FlowNode otherNode) {
super.setValues(otherNode);
incomingFlows = new ArrayList<SequenceFlow>();
if (otherNode.getIncomingFlows() != null && otherNode.getIncomingFlows().size() > 0) {
for (SequenceFlow flow : otherNode.getIncomingFlows()) {
incomingFlows.add(flow.clone());
}
}
outgoingFlows = new ArrayList<SequenceFlow>();
if (otherNode.getOutgoingFlows() != null && otherNode.getOutgoingFlows().size() > 0) {
for (SequenceFlow flow : otherNode.getOutgoingFlows()) {
outgoingFlows.add(flow.clone());
}
}
}
}
......@@ -14,9 +14,7 @@ package org.activiti.bpmn.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Tijs Rademakers
......@@ -30,7 +28,6 @@ public class Process extends BaseElement implements FlowElementsContainer, HasEx
protected List<ActivitiListener> executionListeners = new ArrayList<ActivitiListener>();
protected List<Lane> lanes = new ArrayList<Lane>();
protected List<FlowElement> flowElementList = new ArrayList<FlowElement>();
protected Map<String, FlowElement> flowElementMap = new HashMap<String, FlowElement>(); // The flow elements are twice stored. The map is used for performance when retrieving by id
protected List<Artifact> artifactList = new ArrayList<Artifact>();
protected List<String> candidateStarterUsers = new ArrayList<String>();
protected List<String> candidateStarterGroups = new ArrayList<String>();
......@@ -85,15 +82,7 @@ public class Process extends BaseElement implements FlowElementsContainer, HasEx
}
public FlowElement getFlowElement(String flowElementId) {
FlowElement flowElement = flowElementMap.get(flowElementId);
// It could be the id has changed after insertion into the map,
// So if it is not found, we loop through the list
if (flowElement == null) {
flowElement = findFlowElementInList(flowElementId);
}
return flowElement;
return findFlowElementInList(flowElementId);
}
protected FlowElement findFlowElementInList(String flowElementId) {
......@@ -111,19 +100,12 @@ public class Process extends BaseElement implements FlowElementsContainer, HasEx
public void addFlowElement(FlowElement element) {
flowElementList.add(element);
flowElementMap.put(element.getId(), element);
}
public void removeFlowElement(String elementId) {
FlowElement element = flowElementMap.get(elementId);
if (element == null) {
element = findFlowElementInList(elementId);
}
FlowElement element = findFlowElementInList(elementId);
if (element != null) {
flowElementList.remove(element);
flowElementMap.remove(elementId);
}
}
......
......@@ -128,8 +128,37 @@ public enum ActivitiEventType {
/**
* An existing variable has been deleted.
*/
VARIABLE_DELETED;
VARIABLE_DELETED,
/**
* A task as been assigned. This is thrown alongside with an {@link #ENTITY_UPDATED} event.
*/
TASK_ASSIGNED,
/**
* A task has been completed. Dispatched before the task entity is deleted ({@link #ENTITY_DELETED}).
* If the task is part of a process, this event is dispatched before the process moves on, as a result of
* the task completion. In that case, a {@link #ACTIVITY_COMPLETED} will be dispatched after an event of this type
* for the activity corresponding to the task.
*/
TASK_COMPLETED,
/**
* A new membership has been created.
*/
MEMBERSHIP_CREATED,
/**
* A single membership has been deleted.
*/
MEMBERSHIP_DELETED,
/**
* All memberships in the related group have been deleted. No individual {@link #MEMBERSHIP_DELETED} events will
* be dispatched due to possible performance reasons. The event is dispatched before the memberships are deleted,
* so they can still be accessed in the dispatch method of the listener.
*/
MEMBERSHIPS_DELETED;
public static final ActivitiEventType[] EMPTY_ARRAY = new ActivitiEventType[] {};
......
/* 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.activiti.engine.delegate.event;
/**
* An event related to group memberships.
*
* @author Frederik Heremans
*/
public interface ActivitiMembershipEvent extends ActivitiEvent {
/**
* @return related user. Returns null, if not related to a sigle user but rather to all
* members of the group.
*/
String getUserId();
/**
* @return related group
*/
String getGroupId();
}
......@@ -18,6 +18,7 @@ import org.activiti.engine.delegate.event.ActivitiEntityEvent;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.ActivitiExceptionEvent;
import org.activiti.engine.delegate.event.ActivitiMembershipEvent;
import org.activiti.engine.delegate.event.ActivitiMessageEvent;
import org.activiti.engine.delegate.event.ActivitiSignalEvent;
import org.activiti.engine.delegate.event.ActivitiVariableEvent;
......@@ -25,6 +26,7 @@ import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.context.ExecutionContext;
import org.activiti.engine.impl.persistence.entity.IdentityLinkEntity;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.task.Task;
/**
* Builder class used to create {@link ActivitiEvent} implementations.
......@@ -148,6 +150,13 @@ public class ActivitiEventBuilder {
return newEvent;
}
public static ActivitiMembershipEvent createMembershipEvent(ActivitiEventType type, String groupId, String userId) {
ActivitiMembershipEventImpl newEvent = new ActivitiMembershipEventImpl(type);
newEvent.setUserId(userId);
newEvent.setGroupId(groupId);
return newEvent;
}
protected static void populateEventWithCurrentContext(ActivitiEventImpl event) {
boolean extractedFromContext = false;
if(Context.isExecutionContextActive()) {
......@@ -185,6 +194,10 @@ public class ActivitiEventBuilder {
event.setProcessInstanceId(idLink.getTask().getProcessInstanceId());
event.setExecutionId(idLink.getTask().getExecutionId());
}
} else if(persistendObject instanceof Task) {
event.setProcessInstanceId(((Task)persistendObject).getProcessInstanceId());
event.setExecutionId(((Task)persistendObject).getExecutionId());
event.setProcessDefinitionId(((Task)persistendObject).getProcessDefinitionId());
}
}
}
......
/* 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.activiti.engine.delegate.event.impl;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.ActivitiMembershipEvent;
/**
* Implementation of {@link ActivitiMembershipEvent}.
* @author Frederik Heremans
*/
public class ActivitiMembershipEventImpl extends ActivitiEventImpl implements ActivitiMembershipEvent {
protected String userId;
protected String groupId;
public ActivitiMembershipEventImpl(ActivitiEventType type) {
super(type);
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserId() {
return userId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getGroupId() {
return groupId;
}
}
......@@ -117,7 +117,7 @@ public class UserTaskActivityBehavior extends TaskActivityBehavior {
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void handleAssignments(TaskEntity task, ActivityExecution execution) {
if (taskDefinition.getAssigneeExpression() != null) {
task.setAssignee((String) taskDefinition.getAssigneeExpression().getValue(execution));
task.setAssignee((String) taskDefinition.getAssigneeExpression().getValue(execution), true, false);
}
if (taskDefinition.getOwnerExpression() != null) {
......
......@@ -66,10 +66,10 @@ public class AddIdentityLinkCmd extends NeedsActiveTaskCmd<Void> {
boolean assignedToNoOne = false;
if (IdentityLinkType.ASSIGNEE.equals(type)) {
task.setAssignee(userId);
task.setAssignee(userId, true, true);
assignedToNoOne = userId == null;
} else if (IdentityLinkType.OWNER.equals(type)) {
task.setOwner(userId);
task.setOwner(userId, true);
} else {
task.addIdentityLink(userId, groupId, type);
}
......
......@@ -41,7 +41,7 @@ public class ClaimTaskCmd extends NeedsActiveTaskCmd<Void> {
throw new ActivitiTaskAlreadyClaimedException(task.getId(), task.getAssignee());
}
} else {
task.setAssignee(userId);
task.setAssignee(userId, true, true);
}
} else {
// Task should be assigned to no one
......
......@@ -68,9 +68,9 @@ public class DeleteIdentityLinkCmd extends NeedsActiveTaskCmd<Void> {
protected Void execute(CommandContext commandContext, TaskEntity task) {
if (IdentityLinkType.ASSIGNEE.equals(type)) {
task.setAssignee(null);
task.setAssignee(null, true, true);
} else if (IdentityLinkType.OWNER.equals(type)) {
task.setOwner(null);
task.setOwner(null, true);
} else {
task.deleteIdentityLink(userId, groupId, type);
}
......
......@@ -33,7 +33,7 @@ public class SetTaskDueDateCmd extends NeedsActiveTaskCmd<Void> {
}
protected Void execute(CommandContext commandContext, TaskEntity task) {
task.setDueDate(dueDate);
task.setDueDate(dueDate, true);
return null;
}
......
......@@ -31,7 +31,7 @@ public class SetTaskPriorityCmd extends NeedsActiveTaskCmd<Void> {
}
protected Void execute(CommandContext commandContext, TaskEntity task) {
task.setPriority(priority);
task.setPriority(priority, true);
return null;
}
......
......@@ -13,6 +13,8 @@
package org.activiti.engine.impl.persistence.entity;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.GroupQuery;
import org.activiti.engine.impl.GroupQueryImpl;
......@@ -40,18 +42,41 @@ public class GroupEntityManager extends AbstractManager implements GroupIdentity
public void insertGroup(Group group) {
getDbSqlSession().insert((PersistentObject) group);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_CREATED, group));
}
}
public void updateGroup(GroupEntity updatedGroup) {
CommandContext commandContext = Context.getCommandContext();
DbSqlSession dbSqlSession = commandContext.getDbSqlSession();
dbSqlSession.update(updatedGroup);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, updatedGroup));
}
}
public void deleteGroup(String groupId) {
GroupEntity group = getDbSqlSession().selectById(GroupEntity.class, groupId);
getDbSqlSession().delete("deleteMembershipsByGroupId", groupId);
getDbSqlSession().delete(group);
if(group != null) {
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createMembershipEvent(ActivitiEventType.MEMBERSHIPS_DELETED, groupId, null));
}
getDbSqlSession().delete("deleteMembershipsByGroupId", groupId);
getDbSqlSession().delete(group);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_DELETED, group));
}
}
}
public GroupQuery createNewGroupQuery() {
......
......@@ -16,6 +16,8 @@ package org.activiti.engine.impl.persistence.entity;
import java.util.HashMap;
import java.util.Map;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.persistence.AbstractManager;
......@@ -29,6 +31,11 @@ public class MembershipEntityManager extends AbstractManager implements Membersh
membershipEntity.setUserId(userId);
membershipEntity.setGroupId(groupId);
getDbSqlSession().insert(membershipEntity);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createMembershipEvent(ActivitiEventType.MEMBERSHIP_CREATED, groupId, userId));
}
}
public void deleteMembership(String userId, String groupId) {
......@@ -36,6 +43,11 @@ public class MembershipEntityManager extends AbstractManager implements Membersh
parameters.put("userId", userId);
parameters.put("groupId", groupId);
getDbSqlSession().delete("deleteMembership", parameters);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createMembershipEvent(ActivitiEventType.MEMBERSHIP_DELETED, groupId, userId));
}
}
......
......@@ -117,12 +117,17 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
commandContext.getHistoryManager().recordTaskCreated(this, execution);
if(commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_CREATED, this));
}
}
public void update() {
// Needed to make history work: the setter will also update the historic task
setOwner(this.getOwner());
setAssignee(this.getAssignee());
setAssignee(this.getAssignee(), true, false);
setDelegationState(this.getDelegationState());
setName(this.getName());
setDescription(this.getDescription());
......@@ -135,6 +140,11 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
CommandContext commandContext = Context.getCommandContext();
DbSqlSession dbSqlSession = commandContext.getDbSqlSession();
dbSqlSession.update(this);
if(commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
/** Creates a new task. Embedded state and create time will be initialized.
......@@ -153,6 +163,11 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
getProcessInstance().involveUser(Authentication.getAuthenticatedUserId(), IdentityLinkType.PARTICIPANT);
}
if(Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_COMPLETED, this));
}
Context
.getCommandContext()
.getTaskEntityManager()
......@@ -170,12 +185,12 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
if (getOwner() == null) {
setOwner(getAssignee());
}
setAssignee(userId);
setAssignee(userId, true, true);
}
public void resolve() {
setDelegationState(DelegationState.RESOLVED);
setAssignee(this.owner);
setAssignee(this.owner, true, true);
}
public Object getPersistentState() {
......@@ -486,7 +501,11 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
public void setAssignee(String assignee) {
if (assignee==null && this.assignee==null) {
setAssignee(assignee, false, false);
}
public void setAssignee(String assignee, boolean dispatchAssignmentEvent, boolean dispatchUpdateEvent) {
if (assignee==null && this.assignee==null) {
return;
}
this.assignee = assignee;
......@@ -504,6 +523,18 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
fireEvent(TaskListener.EVENTNAME_ASSIGNMENT);
if(commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
if(dispatchAssignmentEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_ASSIGNED, this));
}
if(dispatchUpdateEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
}
}
......@@ -513,7 +544,11 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
public void setOwner(String owner) {
if (owner==null && this.owner==null) {
setOwner(owner, false);
}
public void setOwner(String owner, boolean dispatchUpdateEvent) {
if (owner==null && this.owner==null) {
return;
}
// if (owner!=null && owner.equals(this.owner)) {
......@@ -530,6 +565,13 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
if (owner != null && processInstanceId != null) {
getProcessInstance().involveUser(owner, IdentityLinkType.PARTICIPANT);
}
if(dispatchUpdateEvent && commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
if(dispatchUpdateEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
}
}
......@@ -539,14 +581,25 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
public void setDueDate(Date dueDate) {
this.dueDate = dueDate;
CommandContext commandContext = Context.getCommandContext();
if (commandContext!=null) {
commandContext
.getHistoryManager()
.recordTaskDueDateChange(id, dueDate);
}
setDueDate(dueDate, false);
}
public void setDueDate(Date dueDate, boolean dispatchUpdateEvent) {
this.dueDate = dueDate;
CommandContext commandContext = Context.getCommandContext();
if (commandContext!=null) {
commandContext
.getHistoryManager()
.recordTaskDueDateChange(id, dueDate);
if(dispatchUpdateEvent && commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
if(dispatchUpdateEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
}
}
public void setDueDateWithoutCascade(Date dueDate) {
......@@ -554,6 +607,10 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
}
public void setPriority(int priority) {
setPriority(priority, false);
}
public void setPriority(int priority, boolean dispatchUpdateEvent) {
this.priority = priority;
CommandContext commandContext = Context.getCommandContext();
......@@ -561,6 +618,13 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
commandContext
.getHistoryManager()
.recordTaskPriorityChange(id, priority);
if(dispatchUpdateEvent && commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
if(dispatchUpdateEvent) {
commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, this));
}
}
}
}
......@@ -818,5 +882,5 @@ public class TaskEntity extends VariableScopeImpl implements Task, DelegateTask,
public void setQueryVariables(List<VariableInstanceEntity> queryVariables) {
this.queryVariables = queryVariables;
}
}
......@@ -20,6 +20,8 @@ import java.util.Map;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.TaskQueryImpl;
import org.activiti.engine.impl.context.Context;
......@@ -79,6 +81,11 @@ public class TaskEntityManager extends AbstractManager {
}
getDbSqlSession().delete(task);
if(commandContext.getEventDispatcher().isEnabled()) {
commandContext.getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_DELETED, task));
}
}
}
......
......@@ -13,6 +13,8 @@
package org.activiti.engine.impl.persistence.entity;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.identity.UserQuery;
......@@ -42,12 +44,22 @@ public class UserEntityManager extends AbstractManager implements UserIdentityMa
public void insertUser(User user) {
getDbSqlSession().insert((PersistentObject) user);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_CREATED, user));
}
}
public void updateUser(UserEntity updatedUser) {
CommandContext commandContext = Context.getCommandContext();
DbSqlSession dbSqlSession = commandContext.getDbSqlSession();
dbSqlSession.update(updatedUser);
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_UPDATED, updatedUser));
}
}
public UserEntity findUserById(String userId) {
......@@ -65,6 +77,11 @@ public class UserEntityManager extends AbstractManager implements UserIdentityMa
getDbSqlSession().delete("deleteMembershipsByUserId", userId);
user.delete();
if(getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_DELETED, user));
}
}
}
......
/* 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.activiti.engine.test.api.event;
import org.activiti.engine.delegate.event.ActivitiEntityEvent;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.ActivitiMembershipEvent;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
/**
* Test case for all {@link ActivitiEvent}s related to groups.
*
* @author Frederik Heremans
*/
public class GroupEventsTest extends PluggableActivitiTestCase {
private TestActivitiEntityEventListener listener;
/**
* Test create, update and delete events of Groups.
*/
public void testGroupEntityEvents() throws Exception {
Group group = null;
try {
group = identityService.newGroup("fred");
group.setName("name");
group.setType("type");
identityService.saveGroup(group);
assertEquals(1, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType());
assertTrue(event.getEntity() instanceof Group);
Group groupFromEvent = (Group) event.getEntity();
assertEquals("fred", groupFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
// Update Group
group.setName("Another name");
identityService.saveGroup(group);
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof Group);
groupFromEvent = (Group) event.getEntity();
assertEquals("fred", groupFromEvent.getId());
assertEquals("Another name", groupFromEvent.getName());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
// Delete Group
identityService.deleteGroup(group.getId());
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertTrue(event.getEntity() instanceof Group);
groupFromEvent = (Group) event.getEntity();
assertEquals("fred", groupFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
} finally {
if (group != null && group.getId() != null) {
identityService.deleteGroup(group.getId());
}
}
}
/**
* Test create, update and delete events of Groups.
*/
public void testGroupMembershipEvents() throws Exception {
TestActivitiEventListener membershipListener = new TestActivitiEventListener();
processEngineConfiguration.getEventDispatcher().addEventListener(membershipListener);
User user = null;
Group group = null;
try {
user = identityService.newUser("kermit");
identityService.saveUser(user);
group = identityService.newGroup("sales");
identityService.saveGroup(group);
// Add membership
membershipListener.clearEventsReceived();
identityService.createMembership("kermit", "sales");
assertEquals(1, membershipListener.getEventsReceived().size());
assertTrue(membershipListener.getEventsReceived().get(0) instanceof ActivitiMembershipEvent);
ActivitiMembershipEvent event = (ActivitiMembershipEvent) membershipListener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.MEMBERSHIP_CREATED, event.getType());
assertEquals("sales", event.getGroupId());
assertEquals("kermit", event.getUserId());
assertNull(event.getExecutionId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
membershipListener.clearEventsReceived();
// Delete membership
identityService.deleteMembership("kermit", "sales");
assertEquals(1, membershipListener.getEventsReceived().size());
assertTrue(membershipListener.getEventsReceived().get(0) instanceof ActivitiMembershipEvent);
event = (ActivitiMembershipEvent) membershipListener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.MEMBERSHIP_DELETED, event.getType());
assertEquals("sales", event.getGroupId());
assertEquals("kermit", event.getUserId());
assertNull(event.getExecutionId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
membershipListener.clearEventsReceived();
// Deleting group will dispatch an event, informing ALL memberships are deleted
identityService.createMembership("kermit", "sales");
membershipListener.clearEventsReceived();
identityService.deleteGroup(group.getId());
assertEquals(2, membershipListener.getEventsReceived().size());
assertTrue(membershipListener.getEventsReceived().get(0) instanceof ActivitiMembershipEvent);
event = (ActivitiMembershipEvent) membershipListener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.MEMBERSHIPS_DELETED, event.getType());
assertEquals("sales", event.getGroupId());
assertNull(event.getUserId());
assertNull(event.getExecutionId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
membershipListener.clearEventsReceived();
} finally {
processEngineConfiguration.getEventDispatcher().removeEventListener(membershipListener);
if(user != null) {
identityService.deleteUser(user.getId());
}
if(group != null) {
identityService.deleteGroup(group.getId());
}
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
listener = new TestActivitiEntityEventListener(Group.class);
processEngineConfiguration.getEventDispatcher().addEventListener(listener);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
if (listener != null) {
processEngineConfiguration.getEventDispatcher().removeEventListener(listener);
}
}
}
/* 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.activiti.engine.test.api.event;
import java.util.Date;
import org.activiti.engine.delegate.event.ActivitiEntityEvent;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.Deployment;
/**
* Test case for all {@link ActivitiEvent}s related to tasks.
*
* @author Frederik Heremans
*/
public class TaskEventsTest extends PluggableActivitiTestCase {
private TestActivitiEntityEventListener listener;
/**
* Check create, update and delete events for a task.
*/
@Deployment(resources= {"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testTaskEventsInProcess() throws Exception {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
assertNotNull(processInstance);
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId())
.singleResult();
assertNotNull(task);
// Check create event
assertEquals(1, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
Task taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
// Update duedate, owner and priority should trigger update-event
taskService.setDueDate(task.getId(), new Date());
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertExecutionDetails(event, processInstance);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
listener.clearEventsReceived();
taskService.setPriority(task.getId(), 12);
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
taskService.setOwner(task.getId(), "kermit");
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
// Updating detached task and calling saveTask should trigger a single update-event
task = taskService.createTaskQuery().processInstanceId(processInstance.getId())
.singleResult();
task.setDueDate(new Date());
task.setOwner("john");
taskService.saveTask(task);
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
// Check delete-event on complete
taskService.complete(task.getId());
assertEquals(2, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.TASK_COMPLETED, event.getType());
assertExecutionDetails(event, processInstance);
event = (ActivitiEntityEvent) listener.getEventsReceived().get(1);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertExecutionDetails(event, processInstance);
}
@Deployment(resources= {"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testTaskAssignmentEventInProcess() throws Exception {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
assertNotNull(processInstance);
listener.clearEventsReceived();
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId())
.singleResult();
assertNotNull(task);
// Set assignee through API
taskService.setAssignee(task.getId(), "kermit");
assertEquals(2, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.TASK_ASSIGNED, event.getType());
assertTrue(event.getEntity() instanceof Task);
Task taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertEquals("kermit", taskFromEvent.getAssignee());
assertExecutionDetails(event, processInstance);
event = (ActivitiEntityEvent) listener.getEventsReceived().get(1);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
// Set assignee through updateTask
task = taskService.createTaskQuery().processInstanceId(processInstance.getId())
.singleResult();
task.setAssignee("newAssignee");
taskService.saveTask(task);
assertEquals(2, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.TASK_ASSIGNED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertEquals("newAssignee", taskFromEvent.getAssignee());
assertExecutionDetails(event, processInstance);
event = (ActivitiEntityEvent) listener.getEventsReceived().get(1);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
assertExecutionDetails(event, processInstance);
listener.clearEventsReceived();
}
/**
* Check events related to process instance delete and standalone task delete.
*/
@Deployment(resources= {"org/activiti/engine/test/api/runtime/oneTaskProcess.bpmn20.xml"})
public void testDeleteEventDoesNotDispathComplete() throws Exception {
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("oneTaskProcess");
assertNotNull(processInstance);
listener.clearEventsReceived();
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId())
.singleResult();
assertNotNull(task);
// Delete process, should delete task as well, but not complete
runtimeService.deleteProcessInstance(processInstance.getId(), "testing task delete events");
assertEquals(1, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertTrue(event.getEntity() instanceof Task);
Task taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertExecutionDetails(event, processInstance);
try {
task = taskService.newTask();
task.setCategory("123");
task.setDescription("Description");
taskService.saveTask(task);
listener.clearEventsReceived();
// Delete standalone task, only a delete-event should be dispatched
taskService.deleteTask(task.getId());
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
} finally {
if(task != null) {
String taskId = task.getId();
task = taskService.createTaskQuery().taskId(taskId).singleResult();
if(task != null) {
// If task still exists, delete it to have a clean DB after test
taskService.deleteTask(taskId);
}
historyService.deleteHistoricTaskInstance(taskId);
}
}
}
/**
* Check all events for tasks not related to a process-instance
*/
public void testStandaloneTaskEvents() throws Exception {
Task task = null;
try {
task = taskService.newTask();
task.setCategory("123");
task.setDescription("Description");
taskService.saveTask(task);
assertEquals(1, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
Task taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
listener.clearEventsReceived();
// Update task
taskService.setOwner(task.getId(), "owner");
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertEquals("owner", taskFromEvent.getOwner());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
listener.clearEventsReceived();
// Assign task
taskService.setAssignee(task.getId(), "kermit");
assertEquals(2, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.TASK_ASSIGNED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertEquals("kermit", taskFromEvent.getAssignee());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(1);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
listener.clearEventsReceived();
// Complete task
taskService.complete(task.getId());
assertEquals(2, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.TASK_COMPLETED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(1);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertTrue(event.getEntity() instanceof Task);
taskFromEvent = (Task) event.getEntity();
assertEquals(task.getId(), taskFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getProcessInstanceId());
assertNull(event.getExecutionId());
} finally {
if(task != null) {
String taskId = task.getId();
task = taskService.createTaskQuery().taskId(taskId).singleResult();
if(task != null) {
// If task still exists, delete it to have a clean DB after test
taskService.deleteTask(taskId);
}
historyService.deleteHistoricTaskInstance(taskId);
}
}
}
protected void assertExecutionDetails(ActivitiEvent event, ProcessInstance processInstance) {
assertEquals(processInstance.getId(), event.getProcessInstanceId());
assertEquals(processInstance.getId(), event.getExecutionId());
assertEquals(processInstance.getProcessDefinitionId(), event.getProcessDefinitionId());
}
@Override
protected void setUp() throws Exception {
super.setUp();
listener = new TestActivitiEntityEventListener(Task.class);
processEngineConfiguration.getEventDispatcher().addEventListener(listener);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
if(listener != null) {
processEngineConfiguration.getEventDispatcher().removeEventListener(listener);
}
}
}
/* 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.activiti.engine.test.api.event;
import org.activiti.engine.delegate.event.ActivitiEntityEvent;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.test.PluggableActivitiTestCase;
/**
* Test case for all {@link ActivitiEvent}s related to users.
*
* @author Frederik Heremans
*/
public class UserEventsTest extends PluggableActivitiTestCase {
private TestActivitiEntityEventListener listener;
/**
* Test create, update and delete events of users.
*/
public void testUserEntityEvents() throws Exception {
User user = null;
try {
user = identityService.newUser("fred");
user.setFirstName("Frederik");
user.setLastName("Heremans");
identityService.saveUser(user);
assertEquals(1, listener.getEventsReceived().size());
ActivitiEntityEvent event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType());
assertTrue(event.getEntity() instanceof User);
User userFromEvent = (User) event.getEntity();
assertEquals("fred", userFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
// Update user
user.setFirstName("Anna");
identityService.saveUser(user);
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_UPDATED, event.getType());
assertTrue(event.getEntity() instanceof User);
userFromEvent = (User) event.getEntity();
assertEquals("fred", userFromEvent.getId());
assertEquals("Anna", userFromEvent.getFirstName());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
// Delete user
identityService.deleteUser(user.getId());
assertEquals(1, listener.getEventsReceived().size());
event = (ActivitiEntityEvent) listener.getEventsReceived().get(0);
assertEquals(ActivitiEventType.ENTITY_DELETED, event.getType());
assertTrue(event.getEntity() instanceof User);
userFromEvent = (User) event.getEntity();
assertEquals("fred", userFromEvent.getId());
assertNull(event.getProcessDefinitionId());
assertNull(event.getExecutionId());
assertNull(event.getProcessInstanceId());
listener.clearEventsReceived();
} finally {
if (user != null && user.getId() != null) {
identityService.deleteUser(user.getId());
}
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
listener = new TestActivitiEntityEventListener(User.class);
processEngineConfiguration.getEventDispatcher().addEventListener(listener);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
if (listener != null) {
processEngineConfiguration.getEventDispatcher().removeEventListener(listener);
}
}
}
......@@ -88,7 +88,7 @@ public class TaskAttachmentCollectionResource extends TaskBaseResource {
throw new ActivitiIllegalArgumentException("Attachment name is required.");
}
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(req.getType(), task.getId(), null, req.getName(),
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(req.getType(), task.getId(), task.getProcessInstanceId(), req.getName(),
req.getDescription(), req.getExternalUrl());
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory().createAttachmentResponse(this, createdAttachment);
......@@ -125,7 +125,7 @@ public class TaskAttachmentCollectionResource extends TaskBaseResource {
throw new ActivitiIllegalArgumentException("Attachment content is required.");
}
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(type, task.getId(), null, name,
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(type, task.getId(), task.getProcessInstanceId(), name,
description, uploadItem.getInputStream());
setStatus(Status.SUCCESS_CREATED);
......
......@@ -147,9 +147,6 @@ public class TaskResource extends TaskBaseResource {
}
protected void claimTask(Task task, TaskActionRequest actionRequest) {
if(actionRequest.getAssignee() == null) {
throw new ActivitiIllegalArgumentException("An assignee is required when claiming a task.");
}
// In case the task is already claimed, a ActivitiTaskAlreadyClaimedException is thown and converted to
// a CONFLICT response by the StatusService
ActivitiUtil.getTaskService().claim(task.getId(), actionRequest.getAssignee());
......
......@@ -119,6 +119,7 @@ public class UserCollectionResourceTest extends BaseRestTestCase {
requestNode.put("id", "testuser");
requestNode.put("firstName", "Frederik");
requestNode.put("lastName", "Heremans");
requestNode.put("password", "test");
requestNode.put("email", "no-reply@activiti.org");
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_USER_COLLECTION, "testuser"));
......
......@@ -481,16 +481,16 @@ public class TaskResourceTest extends BaseRestTestCase {
ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_TASK, taskId));
// Claiming without assignee fails
task.setAssignee("fred");
// Claiming without assignee should set asisgnee to null
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("action", "claim");
try {
client.post(requestNode);
fail("Exception expected");
} catch(ResourceException expected) {
assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, expected.getStatus());
assertEquals("An assignee is required when claiming a task.", expected.getStatus().getDescription());
}
client.post(requestNode);
task = taskService.createTaskQuery().taskId(taskId).singleResult();
assertNotNull(task);
assertNull(task.getAssignee());
assertEquals(1L, taskService.createTaskQuery().taskCandidateUser("newAssignee").count());
// Claim the task and check result
requestNode.put("assignee", "newAssignee");
......
......@@ -5288,7 +5288,7 @@ In case the variable is a binary variable or serializable, the <literal>valueUrl
"action" : "claim",
"assignee" : "userWhoClaims"
}</programlisting>
Claims the task by the given assignee. The assignee is required.
Claims the task by the given assignee. If the assignee is <literal>null</literal>, the task is assigned to no-one, claimable agian.
</para>
<para>
<emphasis role="bold">Delegate a task - Body JSON:</emphasis>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册