提交 cb7307f7 编写于 作者: T tijsrademakers

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

/* 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.cdi.impl.event;
import java.util.HashSet;
import java.util.Set;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.cdi.BusinessProcessEventType;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.parse.BpmnParseHandler;
/**
* {@link BpmnParseHandler} registering the {@link CdiExecutionListener} for
* distributing execution events using the cdi event infrastructure
*
* @author Daniel Meyer
* @author Joram Barrez
*/
public class CdiEventSupportBpmnParseHandler implements BpmnParseHandler {
protected static final Set<Class<? extends BaseElement>> supportedTypes = new HashSet<Class<? extends BaseElement>>();
static {
supportedTypes.add(StartEvent.class);
supportedTypes.add(EndEvent.class);
supportedTypes.add(ExclusiveGateway.class);
supportedTypes.add(InclusiveGateway.class);
supportedTypes.add(ParallelGateway.class);
supportedTypes.add(ScriptTask.class);
supportedTypes.add(ServiceTask.class);
supportedTypes.add(BusinessRuleTask.class);
supportedTypes.add(Task.class);
supportedTypes.add(ManualTask.class);
supportedTypes.add(UserTask.class);
supportedTypes.add(EndEvent.class);
supportedTypes.add(SubProcess.class);
supportedTypes.add(CallActivity.class);
supportedTypes.add(SendTask.class);
supportedTypes.add(ReceiveTask.class);
supportedTypes.add(EventGateway.class);
supportedTypes.add(Transaction.class);
supportedTypes.add(ThrowEvent.class);
supportedTypes.add(TimerEventDefinition.class);
supportedTypes.add(ErrorEventDefinition.class);
supportedTypes.add(SignalEventDefinition.class);
supportedTypes.add(SequenceFlow.class);
}
public Set<Class< ? extends BaseElement>> getHandledTypes() {
return supportedTypes;
}
public void parse(BpmnParse bpmnParse, BaseElement element) {
if (element instanceof SequenceFlow) {
TransitionImpl transition = bpmnParse.getSequenceFlows().get(element.getId());
transition.addExecutionListener(new CdiExecutionListener(transition.getId()));
} else {
ActivityImpl activity = bpmnParse.getCurrentScope().findActivity(element.getId());
if (activity != null) {
addStartEventListener(activity);
addEndEventListener(activity);
}
}
}
protected void addEndEventListener(ActivityImpl activity) {
activity.addExecutionListener(ExecutionListener.EVENTNAME_END, new CdiExecutionListener(activity.getId(), BusinessProcessEventType.END_ACTIVITY));
}
protected void addStartEventListener(ActivityImpl activity) {
activity.addExecutionListener(ExecutionListener.EVENTNAME_START, new CdiExecutionListener(activity.getId(), BusinessProcessEventType.START_ACTIVITY));
}
}
/* 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.cdi.impl.event;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.cdi.BusinessProcessEventType;
import org.activiti.cdi.impl.event.CdiExecutionListener;
import org.activiti.engine.BpmnParseListener;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.util.xml.Element;
import org.activiti.engine.impl.variable.VariableDeclaration;
/**
* {@link BpmnParseListener} registering the {@link CdiExecutionListener} for
* distributing execution events using the cdi event infrastructure
*
* @author Daniel Meyer
*/
public class CdiEventSupportBpmnParseListener implements BpmnParseListener {
protected void addEndEventListener(ActivityImpl activity) {
activity.addExecutionListener(ExecutionListener.EVENTNAME_END, new CdiExecutionListener(activity.getId(), BusinessProcessEventType.END_ACTIVITY));
}
protected void addStartEventListener(ActivityImpl activity) {
activity.addExecutionListener(ExecutionListener.EVENTNAME_START, new CdiExecutionListener(activity.getId(), BusinessProcessEventType.START_ACTIVITY));
}
@Override
public void parseProcess(Process processElement, ProcessDefinitionEntity processDefinition) {
}
@Override
public void parseStartEvent(StartEvent startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
addStartEventListener(startEventActivity);
addEndEventListener(startEventActivity);
}
@Override
public void parseExclusiveGateway(ExclusiveGateway exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseInclusiveGateway(InclusiveGateway inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseParallelGateway(ParallelGateway parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseScriptTask(ScriptTask scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseServiceTask(ServiceTask serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseBusinessRuleTask(BusinessRuleTask businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseTask(Task taskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseManualTask(ManualTask manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseUserTask(UserTask userTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseEndEvent(EndEvent endEventElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseBoundaryTimerEventDefinition(TimerEventDefinition timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
addStartEventListener(timerActivity);
addEndEventListener(timerActivity);
}
@Override
public void parseBoundaryErrorEventDefinition(ErrorEventDefinition errorEventDefinition, boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseSubProcess(SubProcess subProcessElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseCallActivity(CallActivity callActivityElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
}
@Override
public void parseSequenceFlow(SequenceFlow sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
transition.addExecutionListener(new CdiExecutionListener(transition.getId()));
}
@Override
public void parseSendTask(SendTask sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseMultiInstanceLoopCharacteristics(Activity activityElement, MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
}
@Override
public void parseIntermediateTimerEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity) {
addStartEventListener(timerActivity);
addEndEventListener(timerActivity);
}
@Override
public void parseReceiveTask(ReceiveTask receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseIntermediateSignalCatchEventDefinition(SignalEventDefinition signalEventDefinition, ActivityImpl signalActivity) {
addStartEventListener(signalActivity);
addEndEventListener(signalActivity);
}
@Override
public void parseBoundarySignalEventDefinition(SignalEventDefinition signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
addStartEventListener(signalActivity);
addEndEventListener(signalActivity);
}
@Override
public void parseEventBasedGateway(EventGateway eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseTransaction(Transaction transactionElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
}
@Override
public void parseIntermediateThrowEvent(ThrowEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseIntermediateCatchEvent(IntermediateCatchEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
}
@Override
public void parseBoundaryEvent(BoundaryEvent boundaryEventElement, ScopeImpl scopeElement, ActivityImpl nestedActivity) {
}
@Override
public void parseIntermediateMessageCatchEventDefinition(MessageEventDefinition messageEventDefinition, ActivityImpl nestedActivity) {
}
@Override
public void parseBoundaryMessageEventDefinition(MessageEventDefinition element, boolean interrupting, ActivityImpl messageActivity) {
}
}
......@@ -12,9 +12,9 @@
<property name="jobExecutorActivate" value="false" />
<property name="mailServerPort" value="5025" />
<property name="customPostBPMNParseListeners">
<property name="postBpmnParseHandlers">
<list>
<bean class="org.activiti.cdi.impl.event.CdiEventSupportBpmnParseListener" />
<bean class="org.activiti.cdi.impl.event.CdiEventSupportBpmnParseHandler" />
</list>
</property>
......
package org.activiti.engine;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.util.xml.Element;
import org.activiti.engine.impl.variable.VariableDeclaration;
/**
* Base class for implementing a {@link BpmnParseListener} without being forced to implement
* all methods provided, which makes the implementation more robust to future changes.
*
* @author ruecker
* @author Joram Barrez
*/
public class AbstractBpmnParseListener implements BpmnParseListener {
public void parseProcess(Process process, ProcessDefinitionEntity processDefinition) {
}
public void parseStartEvent(StartEvent startEvent, ScopeImpl scope, ActivityImpl startEventActivity) {
}
public void parseExclusiveGateway(ExclusiveGateway exclusiveGateway, ScopeImpl scope, ActivityImpl activity) {
}
public void parseInclusiveGateway(InclusiveGateway inclusiveGateway, ScopeImpl scope, ActivityImpl activity) {
}
public void parseParallelGateway(ParallelGateway parallelGateway, ScopeImpl scope, ActivityImpl activity) {
}
public void parseScriptTask(ScriptTask scriptTask, ScopeImpl scope, ActivityImpl activity) {
}
public void parseServiceTask(ServiceTask serviceTask, ScopeImpl scope, ActivityImpl activity) {
}
public void parseBusinessRuleTask(BusinessRuleTask businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
}
public void parseTask(Task task, ScopeImpl scope, ActivityImpl activity) {
}
public void parseManualTask(ManualTask manualTask, ScopeImpl scope, ActivityImpl activity) {
}
public void parseUserTask(UserTask userTaskElement, ScopeImpl scope, ActivityImpl activity) {
}
public void parseEndEvent(EndEvent endEventElement, ScopeImpl scope, ActivityImpl activity) {
}
public void parseBoundaryTimerEventDefinition(TimerEventDefinition timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
}
public void parseBoundaryErrorEventDefinition(ErrorEventDefinition errorEventDefinition, boolean interrupting, ActivityImpl activity,
ActivityImpl nestedErrorEventActivity) {
}
public void parseSubProcess(SubProcess subProcess, ScopeImpl scope, ActivityImpl activity) {
}
public void parseCallActivity(CallActivity callActivity, ScopeImpl scope, ActivityImpl activity) {
}
public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
}
public void parseSequenceFlow(SequenceFlow sequenceFlow, ScopeImpl scopeElement, TransitionImpl transition) {
}
public void parseSendTask(SendTask sendTask, ScopeImpl scope, ActivityImpl activity) {
}
public void parseMultiInstanceLoopCharacteristics(Activity modelActivity, MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics,
ActivityImpl activity) {
}
public void parseIntermediateTimerEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity) {
}
public void parseReceiveTask(ReceiveTask receiveTask, ScopeImpl scope, ActivityImpl activity) {
}
public void parseIntermediateSignalCatchEventDefinition(SignalEventDefinition signalEventDefinition, ActivityImpl signalActivity) {
}
public void parseIntermediateMessageCatchEventDefinition(MessageEventDefinition messageEventDefinition, ActivityImpl nestedActivity) {
}
public void parseBoundarySignalEventDefinition(SignalEventDefinition signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
}
public void parseEventBasedGateway(EventGateway eventBasedGateway, ScopeImpl scope, ActivityImpl activity) {
}
public void parseTransaction(Transaction transaction, ScopeImpl scope, ActivityImpl activity) {
}
public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
}
public void parseIntermediateThrowEvent(ThrowEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
}
public void parseIntermediateCatchEvent(IntermediateCatchEvent intermediateCatchEvent, ScopeImpl scope, ActivityImpl activity) {
}
public void parseBoundaryEvent(BoundaryEvent boundaryEvent, ScopeImpl scopeElement, ActivityImpl nestedActivity) {
}
public void parseBoundaryMessageEventDefinition(MessageEventDefinition messageEventDefinition, boolean interrupting, ActivityImpl messageActivity) {
}
}
/* 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;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.util.xml.Element;
import org.activiti.engine.impl.variable.VariableDeclaration;
/**
* Listener which can be registered within the engine to receive events during parsing (and
* maybe influence ist). Instead of implementing this interface you might consider to extend
* the {@link AbstractBpmnParseListener}, which contains an empty implementation for all methods
* and makes your implementation easier and more robust to future changes.
*
* Instances of this interface can be injected into the {@link ProcessEngineConfigurationImpl}
* using the pre/postPastListeners lists.
*
* @author Tom Baeyens
* @author Falko Menge
* @author Joram Barrez
*/
public interface BpmnParseListener {
void parseProcess(Process process, ProcessDefinitionEntity processDefinition);
void parseStartEvent(StartEvent startEvent, ScopeImpl scope, ActivityImpl startEventActivity);
void parseExclusiveGateway(ExclusiveGateway exclusiveGateway, ScopeImpl scope, ActivityImpl activity);
void parseInclusiveGateway(InclusiveGateway inclusiveGateway, ScopeImpl scope, ActivityImpl activity);
void parseParallelGateway(ParallelGateway parallelGateway, ScopeImpl scope, ActivityImpl activity);
void parseScriptTask(ScriptTask scriptTask, ScopeImpl scope, ActivityImpl activity);
void parseServiceTask(ServiceTask serviceTask, ScopeImpl scope, ActivityImpl activity);
void parseBusinessRuleTask(BusinessRuleTask businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity);
void parseTask(Task task, ScopeImpl scope, ActivityImpl activity);
void parseManualTask(ManualTask manualTask, ScopeImpl scope, ActivityImpl activity);
void parseUserTask(UserTask userTaskElement, ScopeImpl scope, ActivityImpl activity);
void parseEndEvent(EndEvent endEventElement, ScopeImpl scope, ActivityImpl activity);
void parseBoundaryTimerEventDefinition(TimerEventDefinition timerEventDefinition, boolean interrupting, ActivityImpl timerActivity);
void parseBoundaryErrorEventDefinition(ErrorEventDefinition errorEventDefinition, boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity);
void parseSubProcess(SubProcess subProcess, ScopeImpl scope, ActivityImpl activity);
void parseCallActivity(CallActivity callActivity, ScopeImpl scope, ActivityImpl activity);
void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity);
void parseSequenceFlow(SequenceFlow sequenceFlow, ScopeImpl scopeElement, TransitionImpl transition);
void parseSendTask(SendTask sendTask, ScopeImpl scope, ActivityImpl activity);
void parseMultiInstanceLoopCharacteristics(org.activiti.bpmn.model.Activity modelActivity, MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics, ActivityImpl activity);
void parseIntermediateTimerEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity);
void parseReceiveTask(ReceiveTask receiveTask, ScopeImpl scope, ActivityImpl activity);
void parseIntermediateSignalCatchEventDefinition(SignalEventDefinition signalEventDefinition, ActivityImpl signalActivity);
void parseIntermediateMessageCatchEventDefinition(MessageEventDefinition messageEventDefinition, ActivityImpl nestedActivity);
void parseBoundarySignalEventDefinition(SignalEventDefinition signalEventDefinition, boolean interrupting, ActivityImpl signalActivity);
void parseEventBasedGateway(EventGateway eventBasedGateway, ScopeImpl scope, ActivityImpl activity);
void parseTransaction(Transaction transaction, ScopeImpl scope, ActivityImpl activity);
void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity);
void parseIntermediateThrowEvent(ThrowEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity);
void parseIntermediateCatchEvent(IntermediateCatchEvent intermediateCatchEvent, ScopeImpl scope, ActivityImpl activity);
void parseBoundaryEvent(BoundaryEvent boundaryEvent, ScopeImpl scopeElement, ActivityImpl nestedActivity);
void parseBoundaryMessageEventDefinition(MessageEventDefinition messageEventDefinition, boolean interrupting, ActivityImpl messageActivity);
}
......@@ -18,8 +18,8 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
......@@ -28,65 +28,26 @@ import javax.xml.stream.XMLStreamReader;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.ActivitiListener;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.Artifact;
import org.activiti.bpmn.model.Association;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.CancelEventDefinition;
import org.activiti.bpmn.model.DataAssociation;
import org.activiti.bpmn.model.DataSpec;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.EventSubProcess;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FieldExtension;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Gateway;
import org.activiti.bpmn.model.GraphicInfo;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.Import;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.Interface;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.Message;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.TerminateEventDefinition;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.bpmn.model.parse.Problem;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.BpmnParseListener;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.EventBasedGatewayActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.EventSubProcessStartEventActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.IntermediateCatchEventActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.WebServiceActivityBehavior;
import org.activiti.engine.impl.bpmn.data.AbstractDataAssociation;
import org.activiti.engine.impl.bpmn.data.Assignment;
import org.activiti.engine.impl.bpmn.data.ClassStructureDefinition;
......@@ -108,26 +69,13 @@ import org.activiti.engine.impl.bpmn.webservice.MessageImplicitDataOutputAssocia
import org.activiti.engine.impl.bpmn.webservice.Operation;
import org.activiti.engine.impl.bpmn.webservice.OperationImplementation;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.el.UelExpressionCondition;
import org.activiti.engine.impl.form.DefaultStartFormHandler;
import org.activiti.engine.impl.form.DefaultTaskFormHandler;
import org.activiti.engine.impl.form.StartFormHandler;
import org.activiti.engine.impl.form.TaskFormHandler;
import org.activiti.engine.impl.jobexecutor.TimerCatchIntermediateEventJobHandler;
import org.activiti.engine.impl.jobexecutor.TimerDeclarationImpl;
import org.activiti.engine.impl.jobexecutor.TimerDeclarationType;
import org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler;
import org.activiti.engine.impl.jobexecutor.TimerStartEventJobHandler;
import org.activiti.engine.impl.persistence.entity.DeploymentEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.HasDIBounds;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.impl.util.ReflectUtil;
import org.activiti.engine.impl.util.io.InputStreamSource;
import org.activiti.engine.impl.util.io.ResourceStreamSource;
......@@ -135,7 +83,6 @@ import org.activiti.engine.impl.util.io.StreamSource;
import org.activiti.engine.impl.util.io.StringStreamSource;
import org.activiti.engine.impl.util.io.UrlStreamSource;
import org.activiti.engine.impl.util.xml.Element;
import org.activiti.engine.impl.variable.VariableDeclaration;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -150,12 +97,10 @@ public class BpmnParse implements BpmnXMLConstants {
protected static final Logger LOGGER = LoggerFactory.getLogger(BpmnParse.class);
public static final String PROPERTYNAME_DOCUMENTATION = "documentation";
public static final String PROPERTYNAME_INITIAL = "initial";
public static final String PROPERTYNAME_INITIATOR_VARIABLE_NAME = "initiatorVariableName";
public static final String PROPERTYNAME_CONDITION = "condition";
public static final String PROPERTYNAME_CONDITION_TEXT = "conditionText";
public static final String PROPERTYNAME_VARIABLE_DECLARATIONS = "variableDeclarations";
public static final String PROPERTYNAME_TIMER_DECLARATION = "timerDeclarations";
public static final String PROPERTYNAME_ISEXPANDED = "isExpanded";
public static final String PROPERTYNAME_START_TIMER = "timerStart";
......@@ -164,16 +109,12 @@ public class BpmnParse implements BpmnXMLConstants {
public static final String PROPERTYNAME_ERROR_EVENT_DEFINITIONS = "errorEventDefinitions";
public static final String PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION = "eventDefinitions";
/* process start authorization specific finals */
protected static final String POTENTIAL_STARTER = "potentialStarter";
protected static final String CANDIDATE_STARTER_USERS_EXTENSION = "candidateStarterUsers";
protected static final String CANDIDATE_STARTER_GROUPS_EXTENSION = "candidateStarterGroups";
protected static final String ATTRIBUTEVALUE_T_FORMAL_EXPRESSION = BpmnParser.BPMN20_NS + ":tFormalExpression";
protected String name;
protected StreamSource streamSource;
protected BpmnModel bpmnModel;
protected String targetNamespace;
/** The deployment to which the parsed process definitions will be added. */
......@@ -184,6 +125,18 @@ public class BpmnParse implements BpmnXMLConstants {
/** A map for storing sequence flow based on their id during parsing. */
protected Map<String, TransitionImpl> sequenceFlows;
protected BpmnParseHandlers bpmnParserHandlers;
protected ProcessDefinitionEntity currentProcessDefinition;
protected FlowElement currentFlowElement;
protected ActivityImpl currentActivity;
protected LinkedList<SubProcess> currentSubprocessStack = new LinkedList<SubProcess>();
protected LinkedList<ScopeImpl> currentScopeStack = new LinkedList<ScopeImpl>();
/**
* Mapping containing values stored during the first phase of parsing since
......@@ -203,9 +156,8 @@ public class BpmnParse implements BpmnXMLConstants {
protected Map<String, XMLImporter> importers = new HashMap<String, XMLImporter>();
protected Map<String, String> prefixs = new HashMap<String, String>();
// Members
// Factories
protected ExpressionManager expressionManager;
protected List<BpmnParseListener> parseListeners;
protected ActivityBehaviorFactory activityBehaviorFactory;
protected ListenerFactory listenerFactory;
......@@ -214,9 +166,9 @@ public class BpmnParse implements BpmnXMLConstants {
*/
public BpmnParse(BpmnParser parser) {
this.expressionManager = parser.getExpressionManager();
this.parseListeners = parser.getParseListeners();
this.activityBehaviorFactory = parser.getActivityBehaviorFactory();
this.listenerFactory = parser.getListenerFactory();
this.bpmnParserHandlers = parser.getBpmnParserHandlers();
this.initializeXSDItemDefinitions();
}
......@@ -424,11 +376,7 @@ public class BpmnParse implements BpmnXMLConstants {
protected void transformProcessDefinitions() {
sequenceFlows = new HashMap<String, TransitionImpl>();
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable() == false) {
LOGGER.info("Ignoring non-executable process with id='" + process.getId() + "'. Set the attribute isExecutable=\"true\" to deploy this process.");
} else {
processDefinitions.add(transformProcess(process));
}
bpmnParserHandlers.parse(this, process);
}
if (processDefinitions.size() > 0) {
......@@ -436,134 +384,49 @@ public class BpmnParse implements BpmnXMLConstants {
}
}
/**
* Parses one process (ie anything inside a &lt;process&gt; element).
*
* @param process
* The 'process' object.
* @return The parsed version of the XML: a {@link ProcessDefinitionImpl}
* object.
*/
public ProcessDefinitionEntity transformProcess(Process process) {
ProcessDefinitionEntity processDefinition = new ProcessDefinitionEntity();
/*
* Mapping object model - bpmn xml: processDefinition.id -> generated by
* activiti engine processDefinition.key -> bpmn id (required)
* processDefinition.name -> bpmn name (optional)
*/
processDefinition.setKey(process.getId());
processDefinition.setName(process.getName());
processDefinition.setCategory(bpmnModel.getTargetNamespace());
processDefinition.setDescription(process.getDocumentation());
processDefinition.setProperty(PROPERTYNAME_DOCUMENTATION, process.getDocumentation()); // Kept for backwards compatibility. See ACT-1020
processDefinition.setTaskDefinitions(new HashMap<String, TaskDefinition>());
processDefinition.setDeploymentId(deployment.getId());
createExecutionListenersOnScope(process.getExecutionListeners(), processDefinition);
for (String candidateUser : process.getCandidateStarterUsers()) {
processDefinition.addCandidateStarterUserIdExpression(expressionManager.createExpression(candidateUser));
}
for (String candidateGroup : process.getCandidateStarterGroups()) {
processDefinition.addCandidateStarterGroupIdExpression(expressionManager.createExpression(candidateGroup));
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing process {}", processDefinition.getKey());
}
processFlowElements(process.getFlowElements(), processDefinition, null);
processArtifacts(process.getArtifacts(), processDefinition);
public void processFlowElements(Collection<FlowElement> flowElements) {
if (process.getIoSpecification() != null) {
IOSpecification ioSpecification = createIOSpecification(process.getIoSpecification());
processDefinition.setIoSpecification(ioSpecification);
}
// Parsing the elements is done in a strict order of types,
// as otherwise certain information might not be available when parsing a certain type.
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseProcess(process, processDefinition);
}
// Using lists as we want to keep the order in which they are defined
List<SequenceFlow> sequenceFlowToParse = new ArrayList<SequenceFlow>();
List<BoundaryEvent> boundaryEventsToParse = new ArrayList<BoundaryEvent>();
return processDefinition;
}
protected void processFlowElements(Collection<FlowElement> flowElements, ScopeImpl scope, SubProcess subProcess) {
// activities
// Activities are parsed first
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof SequenceFlow) continue;
ActivityImpl activity = null;
if (flowElement instanceof StartEvent) {
createStartEvent((StartEvent) flowElement, scope, subProcess);
} else if (flowElement instanceof EndEvent) {
createEndEvent((EndEvent) flowElement, scope);
} else if (flowElement instanceof ServiceTask) {
activity = createServiceTask((ServiceTask) flowElement, scope);
} else if (flowElement instanceof UserTask) {
activity = createUserTask((UserTask) flowElement, scope);
} else if (flowElement instanceof BusinessRuleTask) {
activity = createBusinessRuleTask((BusinessRuleTask) flowElement, scope);
} else if (flowElement instanceof ScriptTask) {
activity = createScriptTask((ScriptTask) flowElement, scope);
} else if (flowElement instanceof Transaction) {
activity = createTransaction((Transaction) flowElement, scope);
} else if (flowElement instanceof SubProcess) {
activity = createSubProcess((SubProcess) flowElement, scope);
} else if (flowElement instanceof CallActivity) {
activity = createCallActivity((CallActivity) flowElement, scope);
} else if (flowElement instanceof ManualTask) {
activity = createManualTask((ManualTask) flowElement, scope);
} else if (flowElement instanceof ReceiveTask) {
activity = createReceiveTask((ReceiveTask) flowElement, scope);
} else if (flowElement instanceof SendTask) {
activity = createSendTask((SendTask) flowElement, scope);
} else if (flowElement instanceof Task) {
activity = createTask((Task) flowElement, scope);
} else if (flowElement instanceof EventGateway) {
activity = createEventBasedGateway((EventGateway) flowElement, scope);
} else if (flowElement instanceof ExclusiveGateway) {
activity = createExclusiveGateway((ExclusiveGateway) flowElement, scope);
} else if (flowElement instanceof InclusiveGateway) {
activity = createInclusiveGateway((InclusiveGateway) flowElement, scope);
} else if (flowElement instanceof ParallelGateway) {
activity = createParallelGateway((ParallelGateway) flowElement, scope);
} else if (flowElement instanceof IntermediateCatchEvent) {
activity = createIntermediateCatchEvent((IntermediateCatchEvent) flowElement, scope);
} else if (flowElement instanceof ThrowEvent) {
activity = createIntermediateThrowEvent((ThrowEvent) flowElement, scope);
// Sequence flow are also flow elements, but are only parsed once every activity is found
if (flowElement instanceof SequenceFlow) {
sequenceFlowToParse.add((SequenceFlow) flowElement);
} else if (flowElement instanceof BoundaryEvent) {
boundaryEventsToParse.add((BoundaryEvent) flowElement);
} else {
bpmnParserHandlers.parse(this, flowElement);
}
if (flowElement instanceof Activity) {
createMultiInstanceLoopCharacteristics((org.activiti.bpmn.model.Activity) flowElement, activity);
}
}
// boundary events
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof BoundaryEvent) {
createBoundaryEvent((BoundaryEvent) flowElement, scope);
}
// Boundary events are parsed after all the regular activities are parsed
for (BoundaryEvent boundaryEvent : boundaryEventsToParse) {
bpmnParserHandlers.parse(this, boundaryEvent);
}
// sequence flows
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof SequenceFlow) {
createSequenceFlow((SequenceFlow) flowElement, scope);
}
for (SequenceFlow sequenceFlow : sequenceFlowToParse) {
bpmnParserHandlers.parse(this, sequenceFlow);
}
// validations after complete model
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof ExclusiveGateway) {
ActivityImpl gatewayActivity = scope.findActivity(flowElement.getId());
ActivityImpl gatewayActivity = getCurrentScope().findActivity(flowElement.getId());
validateExclusiveGateway(gatewayActivity, (ExclusiveGateway) flowElement);
}
}
}
protected void processArtifacts(Collection<Artifact> artifacts, ScopeImpl scope) {
public void processArtifacts(Collection<Artifact> artifacts, ScopeImpl scope) {
// associations
for (Artifact artifact : artifacts) {
if (artifact instanceof Association) {
......@@ -572,211 +435,6 @@ public class BpmnParse implements BpmnXMLConstants {
}
}
/**
* Parses the start events of a certain level in the process (process,
* subprocess or another scope).
*
* @param parentElement
* The 'parent' element that contains the start events (process,
* subprocess).
* @param scope
* The {@link ScopeImpl} to which the start events must be added.
*/
protected void createStartEvent(StartEvent startEvent, ScopeImpl scope, SubProcess subProcess) {
ActivityImpl startEventActivity = createActivityOnScope(startEvent, ELEMENT_EVENT_START, scope);
if (scope instanceof ProcessDefinitionEntity) {
createProcessDefinitionStartEvent(startEventActivity, startEvent, (ProcessDefinitionEntity) scope);
} else {
createScopeStartEvent(startEventActivity, startEvent, scope, subProcess);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseStartEvent(startEvent, scope, startEventActivity);
}
createExecutionListenersOnScope(startEvent.getExecutionListeners(), startEventActivity);
if(scope instanceof ProcessDefinitionEntity) {
selectInitial(startEventActivity, startEvent, (ProcessDefinitionEntity) scope);
createStartFormHandlers(startEvent, (ProcessDefinitionEntity) scope);
}
}
protected void selectInitial(ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (processDefinition.getInitial() == null) {
processDefinition.setInitial(startEventActivity);
} else {
// validate that there is s single none start event / timer start event:
if (startEventActivity.getProperty("type").equals("messageStartEvent") == false) {
String currentInitialType = (String) processDefinition.getInitial().getProperty("type");
if (currentInitialType.equals("messageStartEvent")) {
processDefinition.setInitial(startEventActivity);
} else {
bpmnModel.addProblem("multiple none start events or timer start events not supported on process definition.", startEvent);
}
}
}
}
protected void createProcessDefinitionStartEvent(ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (StringUtils.isNotEmpty(startEvent.getInitiator())) {
processDefinition.setProperty(PROPERTYNAME_INITIATOR_VARIABLE_NAME, startEvent.getInitiator());
}
// all start events share the same behavior:
startEventActivity.setActivityBehavior(activityBehaviorFactory.createNoneStartEventActivityBehavior(startEvent));
if (startEvent.getEventDefinitions().size() > 0) {
EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
if (eventDefinition instanceof TimerEventDefinition) {
createTimerStartEventDefinition((TimerEventDefinition) eventDefinition, startEventActivity, processDefinition);
} else if (eventDefinition instanceof MessageEventDefinition) {
MessageEventDefinition messageDefinition = (MessageEventDefinition) eventDefinition;
if (bpmnModel.containsMessageId(messageDefinition.getMessageRef())) {
String messageName = bpmnModel.getMessage(messageDefinition.getMessageRef()).getName();
if (StringUtils.isEmpty(messageName)) {
bpmnModel.addProblem("messageName is required for a message event", startEvent);
}
messageDefinition.setMessageRef(messageName);
}
EventSubscriptionDeclaration eventSubscription = new EventSubscriptionDeclaration(messageDefinition.getMessageRef(), "message");
startEventActivity.setProperty("type", "messageStartEvent");
eventSubscription.setActivityId(startEventActivity.getId());
// create message event subscription:
eventSubscription.setStartEvent(true);
addEventSubscriptionDeclaration(eventSubscription, messageDefinition, processDefinition);
}
}
}
protected void createStartFormHandlers(StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (processDefinition.getInitial() != null) {
if (startEvent.getId().equals(processDefinition.getInitial().getId())) {
StartFormHandler startFormHandler = new DefaultStartFormHandler();
startFormHandler.parseConfiguration(startEvent.getFormProperties(), startEvent.getFormKey(), deployment, processDefinition);
processDefinition.setStartFormHandler(startFormHandler);
}
}
}
protected void createScopeStartEvent(ActivityImpl startEventActivity, StartEvent startEvent, ScopeImpl scope, SubProcess subProcess) {
Object triggeredByEvent = scope.getProperty("triggeredByEvent");
boolean isTriggeredByEvent = triggeredByEvent != null && ((Boolean) triggeredByEvent == true);
if (isTriggeredByEvent) { // event subprocess
// all start events of an event subprocess share common behavior
EventSubProcessStartEventActivityBehavior activityBehavior =
activityBehaviorFactory.createEventSubProcessStartEventActivityBehavior(startEvent, startEventActivity.getId());
startEventActivity.setActivityBehavior(activityBehavior);
// the scope of the event subscription is the parent of the event
// subprocess (subscription must be created when parent is initialized)
ScopeImpl catchingScope = ((ActivityImpl) scope).getParent();
if (startEvent.getEventDefinitions().size() > 0) {
EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
if (eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition) {
if (scope.getProperty(PROPERTYNAME_INITIAL) == null) {
scope.setProperty(PROPERTYNAME_INITIAL, startEventActivity);
org.activiti.bpmn.model.ErrorEventDefinition modelErrorEvent = (org.activiti.bpmn.model.ErrorEventDefinition) eventDefinition;
if (bpmnModel.containsErrorRef(modelErrorEvent.getErrorCode())) {
String errorCode = bpmnModel.getErrors().get(modelErrorEvent.getErrorCode());
if (StringUtils.isEmpty(errorCode)) {
bpmnModel.addProblem("errorCode is required for an error event", startEvent);
}
modelErrorEvent.setErrorCode(errorCode);
}
createErrorStartEventDefinition(modelErrorEvent, startEventActivity, catchingScope);
} else {
bpmnModel.addProblem("multiple start events not supported for subprocess", subProcess);
}
} else if (eventDefinition instanceof MessageEventDefinition) {
MessageEventDefinition messageDefinition = (MessageEventDefinition) eventDefinition;
if (bpmnModel.containsMessageId(messageDefinition.getMessageRef())) {
String messageName = bpmnModel.getMessage(messageDefinition.getMessageRef()).getName();
if (StringUtils.isEmpty(messageName)) {
bpmnModel.addProblem("messageName is required for a message event", startEvent);
}
messageDefinition.setMessageRef(messageName);
}
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(messageDefinition.getMessageRef(), "message");
eventSubscriptionDeclaration.setActivityId(startEventActivity.getId());
eventSubscriptionDeclaration.setStartEvent(false);
addEventSubscriptionDeclaration(eventSubscriptionDeclaration, messageDefinition, catchingScope);
} else if (eventDefinition instanceof SignalEventDefinition) {
SignalEventDefinition signalDefinition = (SignalEventDefinition) eventDefinition;
if (bpmnModel.containsSignalId(signalDefinition.getSignalRef())) {
String signalName = bpmnModel.getSignal(signalDefinition.getSignalRef()).getName();
if (StringUtils.isEmpty(signalName)) {
bpmnModel.addProblem("signalName is required for a signal event", startEvent);
}
signalDefinition.setSignalRef(signalName);
}
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(signalDefinition.getSignalRef(), "signal");
eventSubscriptionDeclaration.setActivityId(startEventActivity.getId());
eventSubscriptionDeclaration.setStartEvent(false);
addEventSubscriptionDeclaration(eventSubscriptionDeclaration, signalDefinition, catchingScope);
} else {
bpmnModel.addProblem("start event of event subprocess must be of type 'error', 'message' or 'signal' ", startEvent);
}
}
} else { // "regular" subprocess
if(startEvent.getEventDefinitions().size() > 0) {
bpmnModel.addProblem("event definitions only allowed on start event if subprocess is an event subprocess", startEvent);
}
if (scope.getProperty(PROPERTYNAME_INITIAL) == null) {
scope.setProperty(PROPERTYNAME_INITIAL, startEventActivity);
startEventActivity.setActivityBehavior(activityBehaviorFactory.createNoneStartEventActivityBehavior(startEvent));
} else {
bpmnModel.addProblem("multiple start events not supported for subprocess", subProcess);
}
}
}
protected void createErrorStartEventDefinition(org.activiti.bpmn.model.ErrorEventDefinition errorEventDefinition, ActivityImpl startEventActivity, ScopeImpl scope) {
ErrorEventDefinition definition = new ErrorEventDefinition(startEventActivity.getId());
if (StringUtils.isNotEmpty(errorEventDefinition.getErrorCode())) {
definition.setErrorCode(errorEventDefinition.getErrorCode());
}
definition.setPrecedence(10);
addErrorEventDefinition(definition, scope);
}
@SuppressWarnings("unchecked")
protected void addEventSubscriptionDeclaration(EventSubscriptionDeclaration subscription, EventDefinition parsedEventDefinition, ScopeImpl scope) {
List<EventSubscriptionDeclaration> eventDefinitions = (List<EventSubscriptionDeclaration>) scope.getProperty(PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION);
if(eventDefinitions == null) {
eventDefinitions = new ArrayList<EventSubscriptionDeclaration>();
scope.setProperty(PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION, eventDefinitions);
} else {
// if this is a message event, validate that it is the only one with the provided name for this scope
if(subscription.getEventType().equals("message")) {
for (EventSubscriptionDeclaration eventDefinition : eventDefinitions) {
if(eventDefinition.getEventType().equals("message")
&& eventDefinition.getEventName().equals(subscription.getEventName())
&& eventDefinition.isStartEvent() == subscription.isStartEvent()) {
bpmnModel.addProblem("Cannot have more than one message event subscription with name '" + subscription.getEventName() +
"' for scope '"+scope.getId()+"'", parsedEventDefinition);
}
}
}
}
eventDefinitions.add(subscription);
}
public void validateExclusiveGateway(ActivityImpl activity, ExclusiveGateway exclusiveGateway) {
if (activity.getOutgoingTransitions().size() == 0) {
// TODO: double check if this is valid (I think in Activiti yes, since we need start events we will need an end event as well)
......@@ -818,1384 +476,159 @@ public class BpmnParse implements BpmnXMLConstants {
}
}
public ActivityImpl createIntermediateCatchEvent(IntermediateCatchEvent event, ScopeImpl scopeElement) {
ActivityImpl nestedActivity = null;
EventDefinition eventDefinition = null;
if (event.getEventDefinitions().size() > 0) {
eventDefinition = event.getEventDefinitions().get(0);
public IOSpecification createIOSpecification(org.activiti.bpmn.model.IOSpecification specificationModel) {
IOSpecification ioSpecification = new IOSpecification();
for (DataSpec dataInputElement : specificationModel.getDataInputs()) {
ItemDefinition itemDefinition = this.itemDefinitions.get(dataInputElement.getItemSubjectRef());
Data dataInput = new Data(this.targetNamespace + ":" + dataInputElement.getId(), dataInputElement.getId(), itemDefinition);
ioSpecification.addInput(dataInput);
}
if (eventDefinition == null) {
bpmnModel.addProblem("No event definition for intermediate catch event " + event.getId(), event);
nestedActivity = createActivityOnScope(event, ELEMENT_EVENT_CATCH, scopeElement);
} else {
boolean isAfterEventBasedGateway = false;
String eventBasedGatewayId = null;
for (SequenceFlow sequenceFlow : event.getIncomingFlows()) {
FlowElement sourceElement = bpmnModel.getFlowElement(sequenceFlow.getSourceRef());
if (sourceElement instanceof EventGateway) {
isAfterEventBasedGateway = true;
eventBasedGatewayId = sourceElement.getId();
break;
}
}
if (isAfterEventBasedGateway) {
ActivityImpl gatewayActivity = scopeElement.findActivity(eventBasedGatewayId);
nestedActivity = createActivityOnScope(event, ELEMENT_EVENT_CATCH, gatewayActivity);
} else {
nestedActivity = createActivityOnScope(event, ELEMENT_EVENT_CATCH, scopeElement);
}
// Catch event behavior is the same for all types
nestedActivity.setActivityBehavior(activityBehaviorFactory.createIntermediateCatchEventActivityBehavior(event));
if (eventDefinition instanceof TimerEventDefinition) {
createIntermediateTimerEventDefinition((TimerEventDefinition) eventDefinition, nestedActivity, isAfterEventBasedGateway);
} else if (eventDefinition instanceof SignalEventDefinition) {
createIntermediateSignalEventDefinition((SignalEventDefinition) eventDefinition, nestedActivity, isAfterEventBasedGateway);
} else if (eventDefinition instanceof MessageEventDefinition) {
createIntermediateMessageEventDefinition((MessageEventDefinition) eventDefinition, nestedActivity, isAfterEventBasedGateway);
} else {
bpmnModel.addProblem("Unsupported intermediate catch event type.", event);
}
for (DataSpec dataOutputElement : specificationModel.getDataOutputs()) {
ItemDefinition itemDefinition = this.itemDefinitions.get(dataOutputElement.getItemSubjectRef());
Data dataOutput = new Data(this.targetNamespace + ":" + dataOutputElement.getId(), dataOutputElement.getId(), itemDefinition);
ioSpecification.addOutput(dataOutput);
}
createExecutionListenersOnScope(event.getExecutionListeners(), nestedActivity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseIntermediateCatchEvent(event, scopeElement, nestedActivity);
for (String dataInputRef : specificationModel.getDataInputRefs()) {
DataRef dataRef = new DataRef(dataInputRef);
ioSpecification.addInputRef(dataRef);
}
return nestedActivity;
for (String dataOutputRef : specificationModel.getDataOutputRefs()) {
DataRef dataRef = new DataRef(dataOutputRef);
ioSpecification.addOutputRef(dataRef);
}
return ioSpecification;
}
protected void createIntermediateMessageEventDefinition(MessageEventDefinition messageEventDefinition, ActivityImpl nestedActivity, boolean isAfterEventBasedGateway) {
nestedActivity.setProperty("type", "intermediateMessageCatch");
if (bpmnModel.containsMessageId(messageEventDefinition.getMessageRef())) {
String messageName = bpmnModel.getMessage(messageEventDefinition.getMessageRef()).getName();
if (StringUtils.isEmpty(messageName)) {
bpmnModel.addProblem("messageName is required for a message event", messageEventDefinition);
}
messageEventDefinition.setMessageRef(messageName);
public AbstractDataAssociation createDataInputAssociation(DataAssociation dataAssociationElement) {
if (StringUtils.isEmpty(dataAssociationElement.getTargetRef())) {
bpmnModel.addProblem("targetRef is required", dataAssociationElement);
}
EventSubscriptionDeclaration messageDefinition = new EventSubscriptionDeclaration(messageEventDefinition.getMessageRef(), "message");
if(isAfterEventBasedGateway) {
messageDefinition.setActivityId(nestedActivity.getId());
addEventSubscriptionDeclaration(messageDefinition, messageEventDefinition, nestedActivity.getParent());
if (dataAssociationElement.getAssignments().isEmpty()) {
return new MessageImplicitDataInputAssociation(dataAssociationElement.getSourceRef(), dataAssociationElement.getTargetRef());
} else {
nestedActivity.setScope(true);
addEventSubscriptionDeclaration(messageDefinition, messageEventDefinition, nestedActivity);
SimpleDataInputAssociation dataAssociation = new SimpleDataInputAssociation(
dataAssociationElement.getSourceRef(), dataAssociationElement.getTargetRef());
for (org.activiti.bpmn.model.Assignment assigmentElement : dataAssociationElement.getAssignments()) {
if (StringUtils.isNotEmpty(assigmentElement.getFrom()) && StringUtils.isNotEmpty(assigmentElement.getTo())) {
Expression from = this.expressionManager.createExpression(assigmentElement.getFrom());
Expression to = this.expressionManager.createExpression(assigmentElement.getTo());
Assignment assignment = new Assignment(from, to);
dataAssociation.addAssignment(assignment);
}
}
return dataAssociation;
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseIntermediateMessageCatchEventDefinition(messageEventDefinition, nestedActivity);
}
public AbstractDataAssociation createDataOutputAssociation(DataAssociation dataAssociationElement) {
if (StringUtils.isNotEmpty(dataAssociationElement.getSourceRef())) {
return new MessageImplicitDataOutputAssociation(dataAssociationElement.getTargetRef(), dataAssociationElement.getSourceRef());
} else {
Expression transformation = this.expressionManager.createExpression(dataAssociationElement.getTransformation());
AbstractDataAssociation dataOutputAssociation = new TransformationDataOutputAssociation(null, dataAssociationElement.getTargetRef(), transformation);
return dataOutputAssociation;
}
}
public ActivityImpl createIntermediateThrowEvent(ThrowEvent intermediateEvent, ScopeImpl scopeElement) {
ActivityImpl nestedActivityImpl = createActivityOnScope(intermediateEvent, ELEMENT_EVENT_THROW, scopeElement);
protected AbstractDataAssociation parseDataOutputAssociation(Element dataAssociationElement) {
String targetRef = dataAssociationElement.element("targetRef").getText();
ActivityBehavior activityBehavior = null;
EventDefinition eventDefinition = null;
if (intermediateEvent.getEventDefinitions().size() > 0) {
eventDefinition = intermediateEvent.getEventDefinitions().get(0);
if (dataAssociationElement.element("sourceRef") != null) {
String sourceRef = dataAssociationElement.element("sourceRef").getText();
return new MessageImplicitDataOutputAssociation(targetRef, sourceRef);
} else {
Expression transformation = this.expressionManager.createExpression(dataAssociationElement.element("transformation").getText());
AbstractDataAssociation dataOutputAssociation = new TransformationDataOutputAssociation(null, targetRef, transformation);
return dataOutputAssociation;
}
if (eventDefinition instanceof SignalEventDefinition) {
SignalEventDefinition signalEventDefinition = (SignalEventDefinition) eventDefinition;
if (bpmnModel.containsSignalId(signalEventDefinition.getSignalRef())) {
String signalName = bpmnModel.getSignal(signalEventDefinition.getSignalRef()).getName();
if (StringUtils.isEmpty(signalName)) {
bpmnModel.addProblem("signalName is required for a signal event", intermediateEvent);
}
signalEventDefinition.setSignalRef(signalName);
}
nestedActivityImpl.setProperty("type", "intermediateSignalThrow");
EventSubscriptionDeclaration signalDefinition = new EventSubscriptionDeclaration(signalEventDefinition.getSignalRef(), "signal");
signalDefinition.setAsync(signalEventDefinition.isAsync());
activityBehavior = activityBehaviorFactory.createIntermediateThrowSignalEventActivityBehavior(intermediateEvent, signalDefinition);
} else if (eventDefinition instanceof org.activiti.bpmn.model.CompensateEventDefinition) {
CompensateEventDefinition compensateEventDefinition = createCompensateEventDefinition((org.activiti.bpmn.model.CompensateEventDefinition) eventDefinition, scopeElement);
activityBehavior = activityBehaviorFactory.createIntermediateThrowCompensationEventActivityBehavior(intermediateEvent,compensateEventDefinition);
}
protected void createAssociation(Association association, ScopeImpl parentScope) {
if (bpmnModel.getArtifact(association.getSourceRef()) != null ||
bpmnModel.getArtifact(association.getTargetRef()) != null) {
} else if (eventDefinition == null) {
activityBehavior = activityBehaviorFactory.createIntermediateThrowNoneEventActivityBehavior(intermediateEvent);
} else {
bpmnModel.addProblem("Unsupported intermediate throw event type " + eventDefinition, intermediateEvent);
// connected to a text annotation so skipping it
return;
}
nestedActivityImpl.setActivityBehavior(activityBehavior);
createExecutionListenersOnScope(intermediateEvent.getExecutionListeners(), nestedActivityImpl);
ActivityImpl sourceActivity = parentScope.findActivity(association.getSourceRef());
ActivityImpl targetActivity = parentScope.findActivity(association.getTargetRef());
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseIntermediateThrowEvent(intermediateEvent, scopeElement, nestedActivityImpl);
// an association may reference elements that are not parsed as activities (like for instance
// text annotations so do not throw an exception if sourceActivity or targetActivity are null)
// However, we make sure they reference 'something':
if(sourceActivity == null) {
//bpmnModel.addProblem("Invalid reference sourceRef '" + association.getSourceRef() + "' of association element ", association.getId());
} else if(targetActivity == null) {
//bpmnModel.addProblem("Invalid reference targetRef '" + association.getTargetRef() + "' of association element ", association.getId());
} else {
if(sourceActivity != null && sourceActivity.getProperty("type").equals("compensationBoundaryCatch")) {
Object isForCompensation = targetActivity.getProperty(PROPERTYNAME_IS_FOR_COMPENSATION);
if(isForCompensation == null || !(Boolean) isForCompensation) {
bpmnModel.addProblem("compensation boundary catch must be connected to element with isForCompensation=true", association);
} else {
ActivityImpl compensatedActivity = sourceActivity.getParentActivity();
compensatedActivity.setProperty(PROPERTYNAME_COMPENSATION_HANDLER_ID, targetActivity.getId());
}
}
}
return nestedActivityImpl;
}
//Diagram interchange
// /////////////////////////////////////////////////////////////////
protected CompensateEventDefinition createCompensateEventDefinition(org.activiti.bpmn.model.CompensateEventDefinition eventDefinition, ScopeImpl scopeElement) {
if(StringUtils.isNotEmpty(eventDefinition.getActivityRef())) {
if(scopeElement.findActivity(eventDefinition.getActivityRef()) == null) {
bpmnModel.addProblem("Invalid attribute value for 'activityRef': no activity with id '" + eventDefinition.getActivityRef() +
"' in current scope " + scopeElement.getId(), eventDefinition);
public void processDI() {
if (bpmnModel.getLocationMap().size() > 0) {
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable() == false) continue;
ProcessDefinitionEntity processDefinition = getProcessDefinition(process.getId());
if (processDefinition != null) {
processDefinition.setGraphicalNotationDefined(true);
for (String shapeId : bpmnModel.getLocationMap().keySet()) {
if (processDefinition.findActivity(shapeId) != null) {
createBPMNShape(shapeId, bpmnModel.getGraphicInfo(shapeId), processDefinition);
}
}
for (String edgeId : bpmnModel.getFlowLocationMap().keySet()) {
if (bpmnModel.getFlowElement(edgeId) != null) {
createBPMNEdge(edgeId, bpmnModel.getFlowLocationGraphicInfo(edgeId));
}
}
}
}
}
CompensateEventDefinition compensateEventDefinition = new CompensateEventDefinition();
compensateEventDefinition.setActivityRef(eventDefinition.getActivityRef());
compensateEventDefinition.setWaitForCompletion(eventDefinition.isWaitForCompletion());
return compensateEventDefinition;
}
protected void createCatchCompensateEventDefinition(org.activiti.bpmn.model.CompensateEventDefinition compensateEventDefinition, ActivityImpl activity) {
activity.setProperty("type", "compensationBoundaryCatch");
ScopeImpl parent = activity.getParent();
for (ActivityImpl child : parent.getActivities()) {
if (child.getProperty("type").equals("compensationBoundaryCatch") && child != activity ) {
bpmnModel.addProblem("multiple boundary events with compensateEventDefinition not supported on same activity.", compensateEventDefinition);
public void createBPMNShape(String key, GraphicInfo graphicInfo, ProcessDefinitionEntity processDefinition) {
ActivityImpl activity = processDefinition.findActivity(key);
if (activity != null) {
createDIBounds(graphicInfo, activity);
} else {
org.activiti.engine.impl.pvm.process.Lane lane = processDefinition.getLaneForId(key);
if(lane != null) {
// The shape represents a lane
createDIBounds(graphicInfo, lane);
} else {
bpmnModel.addProblem("Invalid reference in 'bpmnElement' attribute, activity " + key + " not found", graphicInfo);
}
}
}
protected ActivityBehavior createBoundaryCancelEventDefinition(CancelEventDefinition cancelEventDefinition, ActivityImpl activity) {
activity.setProperty("type", "cancelBoundaryCatch");
ActivityImpl parent = (ActivityImpl) activity.getParent();
if(!parent.getProperty("type").equals("transaction")) {
bpmnModel.addProblem("boundary event with cancelEventDefinition only supported on transaction subprocesses.", cancelEventDefinition);
}
for (ActivityImpl child : parent.getActivities()) {
if(child.getProperty("type").equals("cancelBoundaryCatch")
&& child != activity ) {
bpmnModel.addProblem("multiple boundary events with cancelEventDefinition not supported on same transaction subprocess.", cancelEventDefinition);
}
}
return activityBehaviorFactory.createCancelBoundaryEventActivityBehavior(cancelEventDefinition);
}
/**
* Parses loopCharacteristics (standardLoop/Multi-instance) of an activity, if
* any is defined.
*/
public void createMultiInstanceLoopCharacteristics(org.activiti.bpmn.model.Activity modelActivity, ActivityImpl activity) {
MultiInstanceActivityBehavior miActivityBehavior = null;
MultiInstanceLoopCharacteristics loopCharacteristics = modelActivity.getLoopCharacteristics();
if (loopCharacteristics == null) {
// nothing to do
return;
}
// Activity Behavior
if (loopCharacteristics.isSequential()) {
miActivityBehavior = activityBehaviorFactory.createSequentialMultiInstanceBehavior(
activity, (AbstractBpmnActivityBehavior) activity.getActivityBehavior());
} else {
miActivityBehavior = activityBehaviorFactory.createParallelMultiInstanceBehavior(
activity, (AbstractBpmnActivityBehavior) activity.getActivityBehavior());
}
// ActivityImpl settings
activity.setScope(true);
activity.setProperty("multiInstance", loopCharacteristics.isSequential() ? "sequential" : "parallel");
activity.setActivityBehavior(miActivityBehavior);
// loopcardinality
if (StringUtils.isNotEmpty(loopCharacteristics.getLoopCardinality())) {
miActivityBehavior.setLoopCardinalityExpression(expressionManager.createExpression(loopCharacteristics.getLoopCardinality()));
}
// completion condition
if (StringUtils.isNotEmpty(loopCharacteristics.getCompletionCondition())) {
miActivityBehavior.setCompletionConditionExpression(expressionManager.createExpression(loopCharacteristics.getCompletionCondition()));
}
// activiti:collection
if (StringUtils.isNotEmpty(loopCharacteristics.getInputDataItem())) {
if (loopCharacteristics.getInputDataItem().contains("{")) {
miActivityBehavior.setCollectionExpression(expressionManager.createExpression(loopCharacteristics.getInputDataItem()));
} else {
miActivityBehavior.setCollectionVariable(loopCharacteristics.getInputDataItem());
}
}
// activiti:elementVariable
if (StringUtils.isNotEmpty(loopCharacteristics.getElementVariable())) {
miActivityBehavior.setCollectionElementVariable(loopCharacteristics.getElementVariable());
}
// Validation
if (miActivityBehavior.getLoopCardinalityExpression() == null && miActivityBehavior.getCollectionExpression() == null
&& miActivityBehavior.getCollectionVariable() == null) {
bpmnModel.addProblem("Either loopCardinality or loopDataInputRef/activiti:collection must been set.", loopCharacteristics);
}
// Validation
if (miActivityBehavior.getCollectionExpression() == null && miActivityBehavior.getCollectionVariable() == null
&& miActivityBehavior.getCollectionElementVariable() != null) {
bpmnModel.addProblem("LoopDataInputRef/activiti:collection must be set when using inputDataItem or activiti:elementVariable.", loopCharacteristics);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseMultiInstanceLoopCharacteristics(modelActivity, loopCharacteristics, activity);
}
}
/**
* Parses the generic information of an activity element (id, name,
* documentation, etc.), and creates a new {@link ActivityImpl} on the given
* scope element.
*/
public ActivityImpl createActivityOnScope(FlowElement flowElement, String xmlLocalName, ScopeImpl scopeElement) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing activity {}", flowElement.getId());
}
ActivityImpl activity = scopeElement.createActivity(flowElement.getId());
activity.setProperty("name", flowElement.getName());
activity.setProperty("documentation", flowElement.getDocumentation());
if (flowElement instanceof Activity) {
Activity modelActivity = (Activity) flowElement;
activity.setProperty("default", modelActivity.getDefaultFlow());
if(modelActivity.isForCompensation()) {
activity.setProperty(PROPERTYNAME_IS_FOR_COMPENSATION, true);
}
} else if (flowElement instanceof Gateway) {
activity.setProperty("default", ((Gateway) flowElement).getDefaultFlow());
}
activity.setProperty("type", xmlLocalName);
return activity;
}
public String parseDocumentation(Element element) {
List<Element> docElements = element.elements("documentation");
if (docElements.isEmpty()) {
return null;
}
StringBuilder builder = new StringBuilder();
for (Element e: docElements) {
if (builder.length() != 0) {
builder.append("\n\n");
}
builder.append(e.getText().trim());
}
return builder.toString();
}
/**
* Parses an exclusive gateway declaration.
*/
public ActivityImpl createExclusiveGateway(ExclusiveGateway gateway, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(gateway, ELEMENT_GATEWAY_EXCLUSIVE, scope);
activity.setActivityBehavior(activityBehaviorFactory.createExclusiveGatewayActivityBehavior(gateway));
createExecutionListenersOnScope(gateway.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseExclusiveGateway(gateway, scope, activity);
}
return activity;
}
/**
* Parses an inclusive gateway declaration.
*/
public ActivityImpl createInclusiveGateway(InclusiveGateway gateway, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(gateway, ELEMENT_GATEWAY_INCLUSIVE, scope);
activity.setActivityBehavior(activityBehaviorFactory.createInclusiveGatewayActivityBehavior(gateway));
createExecutionListenersOnScope(gateway.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseInclusiveGateway(gateway, scope, activity);
}
return activity;
}
public ActivityImpl createEventBasedGateway(EventGateway gateway, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(gateway, ELEMENT_GATEWAY_EVENT, scope);
activity.setActivityBehavior(activityBehaviorFactory.createEventBasedGatewayActivityBehavior(gateway));
activity.setScope(true);
createExecutionListenersOnScope(gateway.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseEventBasedGateway(gateway, scope, activity);
}
// find all outgoing sequence flows
for (SequenceFlow sequenceFlow : gateway.getOutgoingFlows()) {
FlowElement flowElement = bpmnModel.getFlowElement(sequenceFlow.getTargetRef());
if (flowElement != null && flowElement instanceof IntermediateCatchEvent == false) {
bpmnModel.addProblem("Event based gateway can only be connected to elements of type intermediateCatchEvent.", flowElement);
}
}
return activity;
}
/**
* Parses a parallel gateway declaration.
*/
public ActivityImpl createParallelGateway(ParallelGateway gateway, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(gateway, ELEMENT_GATEWAY_PARALLEL, scope);
activity.setActivityBehavior(activityBehaviorFactory.createParallelGatewayActivityBehavior(gateway));
createExecutionListenersOnScope(gateway.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseParallelGateway(gateway, scope, activity);
}
return activity;
}
/**
* Parses a scriptTask declaration.
*/
public ActivityImpl createScriptTask(ScriptTask scriptTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(scriptTask, ELEMENT_TASK_SCRIPT, scope);
activity.setAsync(scriptTask.isAsynchronous());
activity.setExclusive(!scriptTask.isNotExclusive());
activity.setActivityBehavior(activityBehaviorFactory.createScriptTaskActivityBehavior(scriptTask));
createExecutionListenersOnScope(scriptTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseScriptTask(scriptTask, scope, activity);
}
return activity;
}
/**
* Parses a serviceTask declaration.
*/
public ActivityImpl createServiceTask(ServiceTask serviceTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(serviceTask, ELEMENT_TASK_SERVICE, scope);
activity.setAsync(serviceTask.isAsynchronous());
activity.setExclusive(!serviceTask.isNotExclusive());
// Email, Mule and Shell service tasks
if (StringUtils.isNotEmpty(serviceTask.getType())) {
if (serviceTask.getType().equalsIgnoreCase("mail")) {
validateFieldDeclarationsForEmail(serviceTask, serviceTask.getFieldExtensions());
activity.setActivityBehavior(activityBehaviorFactory.createMailActivityBehavior(serviceTask));
} else if (serviceTask.getType().equalsIgnoreCase("mule")) {
activity.setActivityBehavior(activityBehaviorFactory.createMuleActivityBehavior(serviceTask, bpmnModel));
} else if (serviceTask.getType().equalsIgnoreCase("shell")) {
validateFieldDeclarationsForShell(serviceTask, serviceTask.getFieldExtensions());
activity.setActivityBehavior(activityBehaviorFactory.createShellActivityBehavior(serviceTask));
} else {
bpmnModel.addProblem("Invalid usage of type attribute: '" + serviceTask.getType() + "'.", serviceTask);
}
// activiti:class
} else if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(activityBehaviorFactory.createClassDelegateServiceTask(serviceTask));
// activiti:delegateExpression
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(activityBehaviorFactory.createServiceTaskDelegateExpressionActivityBehavior(serviceTask));
// activiti:expression
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(activityBehaviorFactory.createServiceTaskExpressionActivityBehavior(serviceTask));
// Webservice
} else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(serviceTask.getImplementationType()) &&
StringUtils.isNotEmpty(serviceTask.getOperationRef())) {
if (!this.operations.containsKey(serviceTask.getOperationRef())) {
bpmnModel.addProblem(serviceTask.getOperationRef() + " does not exist", serviceTask);
} else {
WebServiceActivityBehavior webServiceActivityBehavior = activityBehaviorFactory.createWebServiceActivityBehavior(serviceTask);
webServiceActivityBehavior.setOperation(this.operations.get(serviceTask.getOperationRef()));
if (serviceTask.getIoSpecification() != null) {
IOSpecification ioSpecification = this.createIOSpecification(serviceTask.getIoSpecification());
webServiceActivityBehavior.setIoSpecification(ioSpecification);
}
for (DataAssociation dataAssociationElement : serviceTask.getDataInputAssociations()) {
AbstractDataAssociation dataAssociation = this.createDataInputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataInputAssociation(dataAssociation);
}
for (DataAssociation dataAssociationElement : serviceTask.getDataOutputAssociations()) {
AbstractDataAssociation dataAssociation = this.createDataOutputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataOutputAssociation(dataAssociation);
}
activity.setActivityBehavior(webServiceActivityBehavior);
}
} else {
bpmnModel.addProblem("One of the attributes 'class', 'delegateExpression', 'type', 'operation', or 'expression' is mandatory on serviceTask.", serviceTask);
}
createExecutionListenersOnScope(serviceTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseServiceTask(serviceTask, scope, activity);
}
return activity;
}
protected IOSpecification createIOSpecification(org.activiti.bpmn.model.IOSpecification specificationModel) {
IOSpecification ioSpecification = new IOSpecification();
for (DataSpec dataInputElement : specificationModel.getDataInputs()) {
ItemDefinition itemDefinition = this.itemDefinitions.get(dataInputElement.getItemSubjectRef());
Data dataInput = new Data(this.targetNamespace + ":" + dataInputElement.getId(), dataInputElement.getId(), itemDefinition);
ioSpecification.addInput(dataInput);
}
for (DataSpec dataOutputElement : specificationModel.getDataOutputs()) {
ItemDefinition itemDefinition = this.itemDefinitions.get(dataOutputElement.getItemSubjectRef());
Data dataOutput = new Data(this.targetNamespace + ":" + dataOutputElement.getId(), dataOutputElement.getId(), itemDefinition);
ioSpecification.addOutput(dataOutput);
}
for (String dataInputRef : specificationModel.getDataInputRefs()) {
DataRef dataRef = new DataRef(dataInputRef);
ioSpecification.addInputRef(dataRef);
}
for (String dataOutputRef : specificationModel.getDataOutputRefs()) {
DataRef dataRef = new DataRef(dataOutputRef);
ioSpecification.addOutputRef(dataRef);
}
return ioSpecification;
}
protected AbstractDataAssociation createDataInputAssociation(DataAssociation dataAssociationElement) {
if (StringUtils.isEmpty(dataAssociationElement.getTargetRef())) {
bpmnModel.addProblem("targetRef is required", dataAssociationElement);
}
if (dataAssociationElement.getAssignments().isEmpty()) {
return new MessageImplicitDataInputAssociation(dataAssociationElement.getSourceRef(), dataAssociationElement.getTargetRef());
} else {
SimpleDataInputAssociation dataAssociation = new SimpleDataInputAssociation(
dataAssociationElement.getSourceRef(), dataAssociationElement.getTargetRef());
for (org.activiti.bpmn.model.Assignment assigmentElement : dataAssociationElement.getAssignments()) {
if (StringUtils.isNotEmpty(assigmentElement.getFrom()) && StringUtils.isNotEmpty(assigmentElement.getTo())) {
Expression from = this.expressionManager.createExpression(assigmentElement.getFrom());
Expression to = this.expressionManager.createExpression(assigmentElement.getTo());
Assignment assignment = new Assignment(from, to);
dataAssociation.addAssignment(assignment);
}
}
return dataAssociation;
}
}
protected AbstractDataAssociation createDataOutputAssociation(DataAssociation dataAssociationElement) {
if (StringUtils.isNotEmpty(dataAssociationElement.getSourceRef())) {
return new MessageImplicitDataOutputAssociation(dataAssociationElement.getTargetRef(), dataAssociationElement.getSourceRef());
} else {
Expression transformation = this.expressionManager.createExpression(dataAssociationElement.getTransformation());
AbstractDataAssociation dataOutputAssociation = new TransformationDataOutputAssociation(null, dataAssociationElement.getTargetRef(), transformation);
return dataOutputAssociation;
}
}
/**
* Parses a businessRuleTask declaration.
*/
public ActivityImpl createBusinessRuleTask(BusinessRuleTask businessRuleTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(businessRuleTask, ELEMENT_TASK_BUSINESSRULE, scope);
activity.setAsync(businessRuleTask.isAsynchronous());
activity.setExclusive(!businessRuleTask.isNotExclusive());
activity.setActivityBehavior(activityBehaviorFactory.createBusinessRuleTaskActivityBehavior(businessRuleTask));
createExecutionListenersOnScope(businessRuleTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBusinessRuleTask(businessRuleTask, scope, activity);
}
return activity;
}
/**
* Parses a sendTask declaration.
*/
public ActivityImpl createSendTask(SendTask sendTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(sendTask, ELEMENT_TASK_SEND, scope);
activity.setAsync(sendTask.isAsynchronous());
activity.setExclusive(!sendTask.isNotExclusive());
// for e-mail
if (StringUtils.isNotEmpty(sendTask.getType())) {
if (sendTask.getType().equalsIgnoreCase("mail")) {
validateFieldDeclarationsForEmail(sendTask, sendTask.getFieldExtensions());
activity.setActivityBehavior(activityBehaviorFactory.createMailActivityBehavior(sendTask));
} else if (sendTask.getType().equalsIgnoreCase("mule")) {
activity.setActivityBehavior(activityBehaviorFactory.createMuleActivityBehavior(sendTask, bpmnModel));
} else {
bpmnModel.addProblem("Invalid usage of type attribute: '" + sendTask.getType() + "'.", sendTask);
}
// for web service
} else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(sendTask.getImplementationType()) &&
StringUtils.isNotEmpty(sendTask.getOperationRef())) {
if (!this.operations.containsKey(sendTask.getOperationRef())) {
bpmnModel.addProblem(sendTask.getOperationRef() + " does not exist", sendTask);
} else {
WebServiceActivityBehavior webServiceActivityBehavior = activityBehaviorFactory.createWebServiceActivityBehavior(sendTask);
Operation operation = this.operations.get(sendTask.getOperationRef());
webServiceActivityBehavior.setOperation(operation);
if (sendTask.getIoSpecification() != null) {
IOSpecification ioSpecification = this.createIOSpecification(sendTask.getIoSpecification());
webServiceActivityBehavior.setIoSpecification(ioSpecification);
}
for (DataAssociation dataAssociationElement : sendTask.getDataInputAssociations()) {
AbstractDataAssociation dataAssociation = this.createDataInputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataInputAssociation(dataAssociation);
}
for (DataAssociation dataAssociationElement : sendTask.getDataOutputAssociations()) {
AbstractDataAssociation dataAssociation = this.createDataOutputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataOutputAssociation(dataAssociation);
}
activity.setActivityBehavior(webServiceActivityBehavior);
}
} else {
bpmnModel.addProblem("One of the attributes 'type' or 'operation' is mandatory on sendTask.", sendTask);
}
createExecutionListenersOnScope(sendTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseSendTask(sendTask, scope, activity);
}
return activity;
}
protected AbstractDataAssociation parseDataOutputAssociation(Element dataAssociationElement) {
String targetRef = dataAssociationElement.element("targetRef").getText();
if (dataAssociationElement.element("sourceRef") != null) {
String sourceRef = dataAssociationElement.element("sourceRef").getText();
return new MessageImplicitDataOutputAssociation(targetRef, sourceRef);
} else {
Expression transformation = this.expressionManager.createExpression(dataAssociationElement.element("transformation").getText());
AbstractDataAssociation dataOutputAssociation = new TransformationDataOutputAssociation(null, targetRef, transformation);
return dataOutputAssociation;
}
}
protected void validateFieldDeclarationsForEmail(Task task, List<FieldExtension> fieldExtensions) {
boolean toDefined = false;
boolean textOrHtmlDefined = false;
for (FieldExtension fieldExtension : fieldExtensions) {
if (fieldExtension.getFieldName().equals("to")) {
toDefined = true;
}
if (fieldExtension.getFieldName().equals("html")) {
textOrHtmlDefined = true;
}
if (fieldExtension.getFieldName().equals("text")) {
textOrHtmlDefined = true;
}
}
if (!toDefined) {
bpmnModel.addProblem("No recipient is defined on the mail activity", task);
}
if (!textOrHtmlDefined) {
bpmnModel.addProblem("Text or html field should be provided", task);
}
}
protected void validateFieldDeclarationsForShell(Task task, List<FieldExtension> fieldExtensions) {
boolean shellCommandDefined = false;
for (FieldExtension fieldExtension : fieldExtensions) {
String fieldName = fieldExtension.getFieldName();
String fieldValue = fieldExtension.getStringValue();
shellCommandDefined |= fieldName.equals("command");
if ((fieldName.equals("wait") || fieldName.equals("redirectError") || fieldName.equals("cleanEnv")) && !fieldValue.toLowerCase().equals("true")
&& !fieldValue.toLowerCase().equals("false")) {
bpmnModel.addProblem("undefined value for shell " + fieldName + " parameter :" + fieldValue.toString() + ".", task);
}
}
if (!shellCommandDefined) {
bpmnModel.addProblem("No shell command is defined on the shell activity", task);
}
}
/**
* Parses a task with no specific type (behaves as passthrough).
*/
public ActivityImpl createTask(Task task, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(task, ELEMENT_TASK, scope);
activity.setActivityBehavior(activityBehaviorFactory.createTaskActivityBehavior(task));
activity.setAsync(task.isAsynchronous());
activity.setExclusive(!task.isNotExclusive());
createExecutionListenersOnScope(task.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseTask(task, scope, activity);
}
return activity;
}
/**
* Parses a manual task.
*/
public ActivityImpl createManualTask(ManualTask manualTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(manualTask, ELEMENT_TASK_MANUAL, scope);
activity.setActivityBehavior(activityBehaviorFactory.createManualTaskActivityBehavior(manualTask));
activity.setAsync(manualTask.isAsynchronous());
activity.setExclusive(!manualTask.isNotExclusive());
createExecutionListenersOnScope(manualTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseManualTask(manualTask, scope, activity);
}
return activity;
}
/**
* Parses a receive task.
*/
public ActivityImpl createReceiveTask(ReceiveTask receiveTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(receiveTask, ELEMENT_TASK_RECEIVE, scope);
activity.setActivityBehavior(activityBehaviorFactory.createReceiveTaskActivityBehavior(receiveTask));
activity.setAsync(receiveTask.isAsynchronous());
activity.setExclusive(!receiveTask.isNotExclusive());
createExecutionListenersOnScope(receiveTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseReceiveTask(receiveTask, scope, activity);
}
return activity;
}
/**
* Parses a userTask declaration.
*/
public ActivityImpl createUserTask(UserTask userTask, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(userTask, ELEMENT_TASK_USER, scope);
activity.setAsync(userTask.isAsynchronous());
activity.setExclusive(!userTask.isNotExclusive());
TaskDefinition taskDefinition = parseTaskDefinition(userTask, userTask.getId(), (ProcessDefinitionEntity) scope.getProcessDefinition());
activity.setActivityBehavior(activityBehaviorFactory.createUserTaskActivityBehavior(userTask, taskDefinition));
createExecutionListenersOnScope(userTask.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseUserTask(userTask, scope, activity);
}
return activity;
}
public TaskDefinition parseTaskDefinition(UserTask userTask, String taskDefinitionKey, ProcessDefinitionEntity processDefinition) {
TaskFormHandler taskFormHandler = new DefaultTaskFormHandler();
taskFormHandler.parseConfiguration(userTask.getFormProperties(), userTask.getFormKey(), deployment, processDefinition);
TaskDefinition taskDefinition = new TaskDefinition(taskFormHandler);
taskDefinition.setKey(taskDefinitionKey);
processDefinition.getTaskDefinitions().put(taskDefinitionKey, taskDefinition);
if (StringUtils.isNotEmpty(userTask.getName())) {
taskDefinition.setNameExpression(expressionManager.createExpression(userTask.getName()));
}
if (StringUtils.isNotEmpty(userTask.getDocumentation())) {
taskDefinition.setDescriptionExpression(expressionManager.createExpression(userTask.getDocumentation()));
}
if (StringUtils.isNotEmpty(userTask.getAssignee())) {
taskDefinition.setAssigneeExpression(expressionManager.createExpression(userTask.getAssignee()));
}
for (String candidateUser : userTask.getCandidateUsers()) {
taskDefinition.addCandidateUserIdExpression(expressionManager.createExpression(candidateUser));
}
for (String candidateGroup : userTask.getCandidateGroups()) {
taskDefinition.addCandidateGroupIdExpression(expressionManager.createExpression(candidateGroup));
}
// Activiti custom extension
// Task listeners
for (ActivitiListener taskListener : userTask.getTaskListeners()) {
taskDefinition.addTaskListener(taskListener.getEvent(), createTaskListener(taskListener, userTask.getId()));
}
// Due date
if (StringUtils.isNotEmpty(userTask.getDueDate())) {
taskDefinition.setDueDateExpression(expressionManager.createExpression(userTask.getDueDate()));
}
// Priority
if (StringUtils.isNotEmpty(userTask.getPriority())) {
taskDefinition.setPriorityExpression(expressionManager.createExpression(userTask.getPriority()));
}
return taskDefinition;
}
protected TaskListener createTaskListener(ActivitiListener activitiListener, String taskId) {
TaskListener taskListener = null;
if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = listenerFactory.createClassDelegateTaskListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = listenerFactory.createExpressionTaskListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = listenerFactory.createDelegateExpressionTaskListener(activitiListener);
} else {
bpmnModel.addProblem("Element 'class', 'expression' or 'delegateExpression' is mandatory on taskListener for task", activitiListener);
}
return taskListener;
}
/**
* Parses the end events of a certain level in the process (process,
* subprocess or another scope).
*
* @param parentElement
* The 'parent' element that contains the end events (process,
* subprocess).
* @param scope
* The {@link ScopeImpl} to which the end events must be added.
*/
public void createEndEvent(EndEvent endEvent, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(endEvent, ELEMENT_EVENT_END, scope);
EventDefinition eventDefinition = null;
if (endEvent.getEventDefinitions().size() > 0) {
eventDefinition = endEvent.getEventDefinitions().get(0);
}
// Error end event
if (eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition) {
org.activiti.bpmn.model.ErrorEventDefinition errorDefinition = (org.activiti.bpmn.model.ErrorEventDefinition) eventDefinition;
if (bpmnModel.containsErrorRef(errorDefinition.getErrorCode())) {
String errorCode = bpmnModel.getErrors().get(errorDefinition.getErrorCode());
if (StringUtils.isEmpty(errorCode)) {
bpmnModel.addProblem("errorCode is required for an error event", errorDefinition);
}
activity.setProperty("type", "errorEndEvent");
errorDefinition.setErrorCode(errorCode);
}
activity.setActivityBehavior(activityBehaviorFactory.createErrorEndEventActivityBehavior(endEvent, errorDefinition));
// Cancel end event
} else if (eventDefinition instanceof CancelEventDefinition) {
if (scope.getProperty("type")==null || !scope.getProperty("type").equals("transaction")) {
bpmnModel.addProblem("end event with cancelEventDefinition only supported inside transaction subprocess", endEvent);
} else {
activity.setProperty("type", "cancelEndEvent");
activity.setActivityBehavior(activityBehaviorFactory.createCancelEndEventActivityBehavior(endEvent));
}
// Terminate end event
} else if (eventDefinition instanceof TerminateEventDefinition) {
activity.setActivityBehavior(activityBehaviorFactory.createTerminateEndEventActivityBehavior(endEvent));
// None end event
} else if (eventDefinition == null) {
activity.setActivityBehavior(activityBehaviorFactory.createNoneEndEventActivityBehavior(endEvent));
}
createExecutionListenersOnScope(endEvent.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseEndEvent(endEvent, scope, activity);
}
}
/**
* Parses the boundary events of a certain 'level' (process, subprocess or
* other scope).
*
* Note that the boundary events are not parsed during the parsing of the bpmn
* activities, since the semantics are different (boundaryEvent needs to be
* added as nested activity to the reference activity on PVM level).
*
* @param parentElement
* The 'parent' element that contains the activities (process,
* subprocess).
* @param scopeElement
* The {@link ScopeImpl} to which the activities must be added.
*/
public void createBoundaryEvent(BoundaryEvent boundaryEvent, ScopeImpl scopeElement) {
ActivityImpl parentActivity = scopeElement.findActivity(boundaryEvent.getAttachedToRefId());
if (parentActivity == null) {
bpmnModel.addProblem("Invalid reference in boundary event. Make sure that the referenced activity is defined in the same scope as the boundary event",
boundaryEvent);
return;
}
ActivityImpl nestedActivity = createActivityOnScope(boundaryEvent, ELEMENT_EVENT_BOUNDARY, parentActivity);
EventDefinition eventDefinition = null;
if (boundaryEvent.getEventDefinitions().size() > 0) {
eventDefinition = boundaryEvent.getEventDefinitions().get(0);
}
boolean interrupting = boundaryEvent.isCancelActivity();
ActivityBehavior behavior = null;
if (eventDefinition instanceof TimerEventDefinition) {
behavior = activityBehaviorFactory.createBoundaryEventActivityBehavior(boundaryEvent, interrupting, nestedActivity);
createBoundaryTimerEventDefinition((TimerEventDefinition) eventDefinition, interrupting, nestedActivity);
} else if (eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition) {
interrupting = true; // non-interrupting not yet supported
behavior = activityBehaviorFactory.createBoundaryEventActivityBehavior(boundaryEvent, interrupting, nestedActivity);
org.activiti.bpmn.model.ErrorEventDefinition modelErrorEvent = (org.activiti.bpmn.model.ErrorEventDefinition) eventDefinition;
if (bpmnModel.containsErrorRef(modelErrorEvent.getErrorCode())) {
String errorCode = bpmnModel.getErrors().get(modelErrorEvent.getErrorCode());
if (StringUtils.isEmpty(errorCode)) {
bpmnModel.addProblem("errorCode is required for an error event", boundaryEvent);
}
modelErrorEvent.setErrorCode(errorCode);
}
createBoundaryErrorEventDefinition(modelErrorEvent, interrupting, parentActivity, nestedActivity);
} else if (eventDefinition instanceof SignalEventDefinition) {
behavior = activityBehaviorFactory.createBoundaryEventActivityBehavior(boundaryEvent, interrupting, nestedActivity);
createBoundarySignalEventDefinition((SignalEventDefinition) eventDefinition, interrupting, nestedActivity);
} else if (eventDefinition instanceof CancelEventDefinition) {
// always interrupting
behavior = createBoundaryCancelEventDefinition((CancelEventDefinition) eventDefinition, nestedActivity);
} else if (eventDefinition instanceof org.activiti.bpmn.model.CompensateEventDefinition) {
behavior = activityBehaviorFactory.createBoundaryEventActivityBehavior(boundaryEvent, interrupting, nestedActivity);
createCatchCompensateEventDefinition((org.activiti.bpmn.model.CompensateEventDefinition) eventDefinition, nestedActivity);
} else if (eventDefinition instanceof MessageEventDefinition) {
behavior = activityBehaviorFactory.createBoundaryEventActivityBehavior(boundaryEvent, interrupting, nestedActivity);
MessageEventDefinition modelMessageEvent = (MessageEventDefinition) eventDefinition;
if (bpmnModel.containsMessageId(modelMessageEvent.getMessageRef())) {
String messageName = bpmnModel.getMessage(modelMessageEvent.getMessageRef()).getName();
if (StringUtils.isEmpty(messageName)) {
bpmnModel.addProblem("messageName is required for a message event", boundaryEvent);
}
modelMessageEvent.setMessageRef(messageName);
}
createBoundaryMessageEventDefinition((MessageEventDefinition) eventDefinition, interrupting, nestedActivity);
} else {
bpmnModel.addProblem("Unsupported boundary event type", boundaryEvent);
}
nestedActivity.setActivityBehavior(behavior);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundaryEvent(boundaryEvent, scopeElement, nestedActivity);
}
}
/**
* Parses a boundary timer event. The end-result will be that the given nested
* activity will get the appropriate {@link ActivityBehavior}.
*
* @param timerEventDefinition
* The XML element corresponding with the timer event details
* @param interrupting
* Indicates whether this timer is interrupting.
* @param timerActivity
* The activity which maps to the structure of the timer event on the
* boundary of another activity. Note that this is NOT the activity
* onto which the boundary event is attached, but a nested activity
* inside this activity, specifically created for this event.
*/
public void createBoundaryTimerEventDefinition(TimerEventDefinition timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
timerActivity.setProperty("type", "boundaryTimer");
TimerDeclarationImpl timerDeclaration = createTimer(timerEventDefinition, timerActivity, TimerExecuteNestedActivityJobHandler.TYPE);
// ACT-1427
if (interrupting) {
timerDeclaration.setInterruptingTimer(true);
}
addTimerDeclaration(timerActivity.getParent(), timerDeclaration);
if (timerActivity.getParent() instanceof ActivityImpl) {
((ActivityImpl) timerActivity.getParent()).setScope(true);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundaryTimerEventDefinition(timerEventDefinition, interrupting, timerActivity);
}
}
public void createBoundarySignalEventDefinition(SignalEventDefinition signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
signalActivity.setProperty("type", "boundarySignal");
if (bpmnModel.containsSignalId(signalEventDefinition.getSignalRef())) {
String signalName = bpmnModel.getSignal(signalEventDefinition.getSignalRef()).getName();
if (StringUtils.isEmpty(signalName)) {
bpmnModel.addProblem("signalName is required for a signal event", signalEventDefinition);
}
signalEventDefinition.setSignalRef(signalName);
}
EventSubscriptionDeclaration signalDefinition = new EventSubscriptionDeclaration(signalEventDefinition.getSignalRef(), "signal");
signalDefinition.setActivityId(signalActivity.getId());
addEventSubscriptionDeclaration(signalDefinition, signalEventDefinition, signalActivity.getParent());
if (signalActivity.getParent() instanceof ActivityImpl) {
((ActivityImpl) signalActivity.getParent()).setScope(true);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundarySignalEventDefinition(signalEventDefinition, interrupting, signalActivity);
}
}
public void createBoundaryMessageEventDefinition(MessageEventDefinition messageEventDefinition, boolean interrupting, ActivityImpl messageActivity) {
messageActivity.setProperty("type", "boundaryMessage");
EventSubscriptionDeclaration messageDefinition = new EventSubscriptionDeclaration(messageEventDefinition.getMessageRef(), "message");
messageDefinition.setActivityId(messageActivity.getId());
addEventSubscriptionDeclaration(messageDefinition, messageEventDefinition, messageActivity.getParent());
if (messageActivity.getParent() instanceof ActivityImpl) {
((ActivityImpl) messageActivity.getParent()).setScope(true);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundaryMessageEventDefinition(messageEventDefinition, interrupting, messageActivity);
}
}
@SuppressWarnings("unchecked")
protected void createTimerStartEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity, ProcessDefinitionEntity processDefinition) {
timerActivity.setProperty("type", "startTimerEvent");
TimerDeclarationImpl timerDeclaration = createTimer(timerEventDefinition, timerActivity, TimerStartEventJobHandler.TYPE);
timerDeclaration.setJobHandlerConfiguration(processDefinition.getKey());
List<TimerDeclarationImpl> timerDeclarations = (List<TimerDeclarationImpl>) processDefinition.getProperty(PROPERTYNAME_START_TIMER);
if (timerDeclarations == null) {
timerDeclarations = new ArrayList<TimerDeclarationImpl>();
processDefinition.setProperty(PROPERTYNAME_START_TIMER, timerDeclarations);
}
timerDeclarations.add(timerDeclaration);
}
protected void createIntermediateSignalEventDefinition(SignalEventDefinition signalEventDefinition, ActivityImpl signalActivity, boolean isAfterEventBasedGateway) {
signalActivity.setProperty("type", "intermediateSignalCatch");
if (bpmnModel.containsSignalId(signalEventDefinition.getSignalRef())) {
String signalName = bpmnModel.getSignal(signalEventDefinition.getSignalRef()).getName();
if (StringUtils.isEmpty(signalName)) {
bpmnModel.addProblem("signalName is required for a signal event", signalEventDefinition);
}
signalEventDefinition.setSignalRef(signalName);
}
EventSubscriptionDeclaration signalDefinition = new EventSubscriptionDeclaration(signalEventDefinition.getSignalRef(), "signal");
if (isAfterEventBasedGateway) {
signalDefinition.setActivityId(signalActivity.getId());
addEventSubscriptionDeclaration(signalDefinition, signalEventDefinition, signalActivity.getParent());
} else {
signalActivity.setScope(true);
addEventSubscriptionDeclaration(signalDefinition, signalEventDefinition, signalActivity);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseIntermediateSignalCatchEventDefinition(signalEventDefinition, signalActivity);
}
}
protected void createIntermediateTimerEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity, boolean isAfterEventBasedGateway) {
timerActivity.setProperty("type", "intermediateTimer");
TimerDeclarationImpl timerDeclaration = createTimer(timerEventDefinition, timerActivity, TimerCatchIntermediateEventJobHandler.TYPE);
if (isAfterEventBasedGateway) {
addTimerDeclaration(timerActivity.getParent(), timerDeclaration);
} else {
addTimerDeclaration(timerActivity, timerDeclaration);
timerActivity.setScope(true);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseIntermediateTimerEventDefinition(timerEventDefinition, timerActivity);
}
}
protected TimerDeclarationImpl createTimer(TimerEventDefinition timerEventDefinition, ScopeImpl timerActivity, String jobHandlerType) {
TimerDeclarationType type = null;
Expression expression = null;
if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDate())) {
// TimeDate
type = TimerDeclarationType.DATE;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDate());
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeCycle())) {
// TimeCycle
type = TimerDeclarationType.CYCLE;
expression = expressionManager.createExpression(timerEventDefinition.getTimeCycle());
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDuration())) {
// TimeDuration
type = TimerDeclarationType.DURATION;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDuration());
}
// neither date, cycle or duration configured!
if (expression == null) {
bpmnModel.addProblem("Timer needs configuration (either timeDate, timeCycle or timeDuration is needed).", timerEventDefinition);
}
// Parse the timer declaration
// TODO move the timer declaration into the bpmn activity or next to the
// TimerSession
TimerDeclarationImpl timerDeclaration = new TimerDeclarationImpl(expression, type, jobHandlerType);
timerDeclaration.setJobHandlerConfiguration(timerActivity.getId());
timerDeclaration.setExclusive(true);
return timerDeclaration;
}
public void createBoundaryErrorEventDefinition(org.activiti.bpmn.model.ErrorEventDefinition errorEventDefinition,
boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
nestedErrorEventActivity.setProperty("type", "boundaryError");
ScopeImpl catchingScope = nestedErrorEventActivity.getParent();
((ActivityImpl) catchingScope).setScope(true);
ErrorEventDefinition definition = new ErrorEventDefinition(nestedErrorEventActivity.getId());
definition.setErrorCode(errorEventDefinition.getErrorCode());
addErrorEventDefinition(definition, catchingScope);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundaryErrorEventDefinition(errorEventDefinition, interrupting, activity, nestedErrorEventActivity);
}
}
/**
* Checks if the given activity is a child activity of the
* possibleParentActivity.
*/
protected boolean isChildActivity(ActivityImpl activityToCheck, ActivityImpl possibleParentActivity) {
for (ActivityImpl child : possibleParentActivity.getActivities()) {
if (child.getId().equals(activityToCheck.getId()) || isChildActivity(activityToCheck, child)) {
return true;
}
}
return false;
}
@SuppressWarnings("unchecked")
protected void addTimerDeclaration(ScopeImpl scope, TimerDeclarationImpl timerDeclaration) {
List<TimerDeclarationImpl> timerDeclarations = (List<TimerDeclarationImpl>) scope.getProperty(PROPERTYNAME_TIMER_DECLARATION);
if (timerDeclarations == null) {
timerDeclarations = new ArrayList<TimerDeclarationImpl>();
scope.setProperty(PROPERTYNAME_TIMER_DECLARATION, timerDeclarations);
}
timerDeclarations.add(timerDeclaration);
}
@SuppressWarnings("unchecked")
protected void addVariableDeclaration(ScopeImpl scope, VariableDeclaration variableDeclaration) {
List<VariableDeclaration> variableDeclarations = (List<VariableDeclaration>) scope.getProperty(PROPERTYNAME_VARIABLE_DECLARATIONS);
if (variableDeclarations == null) {
variableDeclarations = new ArrayList<VariableDeclaration>();
scope.setProperty(PROPERTYNAME_VARIABLE_DECLARATIONS, variableDeclarations);
}
variableDeclarations.add(variableDeclaration);
}
/**
* Parses a subprocess (formally known as an embedded subprocess): a subprocess
* defined within another process definition.
*
* @param subProcessElement
* The XML element corresponding with the subprocess definition
* @param scope
* The current scope on which the subprocess is defined.
*/
public ActivityImpl createSubProcess(SubProcess subProcess, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(subProcess, ELEMENT_SUBPROCESS, scope);
activity.setAsync(subProcess.isAsynchronous());
activity.setExclusive(!subProcess.isNotExclusive());
boolean triggeredByEvent = false;
if (subProcess instanceof EventSubProcess) {
triggeredByEvent = true;
}
activity.setProperty("triggeredByEvent", triggeredByEvent);
// event subprocesses are not scopes
activity.setScope(!triggeredByEvent);
activity.setActivityBehavior(activityBehaviorFactory.createSubprocActivityBehavior(subProcess));
processFlowElements(subProcess.getFlowElements(), activity, subProcess);
processArtifacts(subProcess.getArtifacts(), activity);
if (subProcess.getIoSpecification() != null) {
IOSpecification ioSpecification = createIOSpecification(subProcess.getIoSpecification());
activity.setIoSpecification(ioSpecification);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseSubProcess(subProcess, scope, activity);
}
return activity;
}
protected ActivityImpl createTransaction(Transaction transaction, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(transaction, ELEMENT_TRANSACTION, scope);
activity.setAsync(transaction.isAsynchronous());
activity.setExclusive(!transaction.isNotExclusive());
activity.setScope(true);
activity.setActivityBehavior(activityBehaviorFactory.createTransactionActivityBehavior(transaction));
processFlowElements(transaction.getFlowElements(), activity, transaction);
processArtifacts(transaction.getArtifacts(), activity);
if (transaction.getIoSpecification() != null) {
IOSpecification ioSpecification = createIOSpecification(transaction.getIoSpecification());
activity.setIoSpecification(ioSpecification);
}
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseTransaction(transaction, scope, activity);
}
return activity;
}
/**
* Parses a call activity (currently only supporting calling subprocesses).
*
* @param callActivityElement
* The XML element defining the call activity
* @param scope
* The current scope on which the call activity is defined.
*/
public ActivityImpl createCallActivity(CallActivity callActivity, ScopeImpl scope) {
ActivityImpl activity = createActivityOnScope(callActivity, ELEMENT_CALL_ACTIVITY, scope);
activity.setScope(true);
activity.setActivityBehavior(activityBehaviorFactory.createCallActivityBehavior(callActivity));
createExecutionListenersOnScope(callActivity.getExecutionListeners(), activity);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseCallActivity(callActivity, scope, activity);
}
return activity;
}
/**
* Parses all sequence flow of a scope.
*
* @param processElement
* The 'process' element wherein the sequence flow are defined.
* @param scope
* The scope to which the sequence flow must be added.
*/
public void createSequenceFlow(SequenceFlow sequenceFlow, ScopeImpl scope) {
// Implicit check: sequence flow cannot cross (sub) process boundaries: we
// don't do a processDefinition.findActivity here
ActivityImpl sourceActivity = scope.findActivity(sequenceFlow.getSourceRef());
ActivityImpl destinationActivity = scope.findActivity(sequenceFlow.getTargetRef());
if (sourceActivity == null) {
bpmnModel.addProblem("Invalid source '" + sequenceFlow.getSourceRef() + "' of sequence flow '" + sequenceFlow.getId() + "'", sequenceFlow);
} else if (destinationActivity == null) {
throw new ActivitiIllegalArgumentException("Invalid destination '" + sequenceFlow.getTargetRef() + "' of sequence flow '" + sequenceFlow.getId() + "'");
} else if(!(sourceActivity.getActivityBehavior() instanceof EventBasedGatewayActivityBehavior)
&& destinationActivity.getActivityBehavior() instanceof IntermediateCatchEventActivityBehavior
&& (destinationActivity.getParentActivity() != null)
&& (destinationActivity.getParentActivity().getActivityBehavior() instanceof EventBasedGatewayActivityBehavior)) {
bpmnModel.addProblem("Invalid incoming sequenceflow " + sequenceFlow.getId() + " for intermediateCatchEvent with id '"
+destinationActivity.getId()+"' connected to an event-based gateway.", sequenceFlow);
} else {
TransitionImpl transition = sourceActivity.createOutgoingTransition(sequenceFlow.getId());
sequenceFlows.put(sequenceFlow.getId(), transition);
transition.setProperty("name", sequenceFlow.getName());
transition.setProperty("documentation", sequenceFlow.getDocumentation());
transition.setDestination(destinationActivity);
if (StringUtils.isNotEmpty(sequenceFlow.getConditionExpression())) {
Condition expressionCondition = new UelExpressionCondition(expressionManager.createExpression(sequenceFlow.getConditionExpression()));
transition.setProperty(PROPERTYNAME_CONDITION_TEXT, sequenceFlow.getConditionExpression());
transition.setProperty(PROPERTYNAME_CONDITION, expressionCondition);
}
createExecutionListenersOnTransition(sequenceFlow.getExecutionListeners(), transition);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseSequenceFlow(sequenceFlow, scope, transition);
}
}
}
protected void createAssociation(Association association, ScopeImpl parentScope) {
if (bpmnModel.getArtifact(association.getSourceRef()) != null ||
bpmnModel.getArtifact(association.getTargetRef()) != null) {
// connected to a text annotation so skipping it
return;
}
ActivityImpl sourceActivity = parentScope.findActivity(association.getSourceRef());
ActivityImpl targetActivity = parentScope.findActivity(association.getTargetRef());
// an association may reference elements that are not parsed as activities (like for instance
// text annotations so do not throw an exception if sourceActivity or targetActivity are null)
// However, we make sure they reference 'something':
if(sourceActivity == null) {
//bpmnModel.addProblem("Invalid reference sourceRef '" + association.getSourceRef() + "' of association element ", association.getId());
} else if(targetActivity == null) {
//bpmnModel.addProblem("Invalid reference targetRef '" + association.getTargetRef() + "' of association element ", association.getId());
} else {
if(sourceActivity != null && sourceActivity.getProperty("type").equals("compensationBoundaryCatch")) {
Object isForCompensation = targetActivity.getProperty(PROPERTYNAME_IS_FOR_COMPENSATION);
if(isForCompensation == null || !(Boolean) isForCompensation) {
bpmnModel.addProblem("compensation boundary catch must be connected to element with isForCompensation=true", association);
} else {
ActivityImpl compensatedActivity = sourceActivity.getParentActivity();
compensatedActivity.setProperty(PROPERTYNAME_COMPENSATION_HANDLER_ID, targetActivity.getId());
}
}
}
}
public void createExecutionListenersOnScope(List<ActivitiListener> activitiListenerList, ScopeImpl scope) {
for (ActivitiListener activitiListener : activitiListenerList) {
scope.addExecutionListener(activitiListener.getEvent(), createExecutionListener(activitiListener));
}
}
public void createExecutionListenersOnTransition(List<ActivitiListener> activitiListenerList, TransitionImpl transition) {
for (ActivitiListener activitiListener : activitiListenerList) {
transition.addExecutionListener(createExecutionListener(activitiListener));
}
}
/**
* Parses an {@link ExecutionListener} implementation for the given
* executionListener element.
*
* @param executionListenerElement
* the XML element containing the executionListener definition.
*/
public ExecutionListener createExecutionListener(ActivitiListener activitiListener) {
ExecutionListener executionListener = null;
if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = listenerFactory.createClassDelegateExecutionListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = listenerFactory.createExpressionExecutionListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = listenerFactory.createDelegateExpressionExecutionListener(activitiListener);
}
return executionListener;
}
protected void addErrorEventDefinition(ErrorEventDefinition errorEventDefinition, ScopeImpl catchingScope) {
List<ErrorEventDefinition> errorEventDefinitions = (List<ErrorEventDefinition>) catchingScope.getProperty(PROPERTYNAME_ERROR_EVENT_DEFINITIONS);
if(errorEventDefinitions == null) {
errorEventDefinitions = new ArrayList<ErrorEventDefinition>();
catchingScope.setProperty(PROPERTYNAME_ERROR_EVENT_DEFINITIONS, errorEventDefinitions);
}
errorEventDefinitions.add(errorEventDefinition);
Collections.sort(errorEventDefinitions, ErrorEventDefinition.comparator);
}
//Diagram interchange
// /////////////////////////////////////////////////////////////////
public void processDI() {
if (bpmnModel.getLocationMap().size() > 0) {
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable() == false) continue;
ProcessDefinitionEntity processDefinition = getProcessDefinition(process.getId());
if (processDefinition != null) {
processDefinition.setGraphicalNotationDefined(true);
for (String shapeId : bpmnModel.getLocationMap().keySet()) {
if (processDefinition.findActivity(shapeId) != null) {
createBPMNShape(shapeId, bpmnModel.getGraphicInfo(shapeId), processDefinition);
}
}
for (String edgeId : bpmnModel.getFlowLocationMap().keySet()) {
if (bpmnModel.getFlowElement(edgeId) != null) {
createBPMNEdge(edgeId, bpmnModel.getFlowLocationGraphicInfo(edgeId));
}
}
}
}
}
}
public void createBPMNShape(String key, GraphicInfo graphicInfo, ProcessDefinitionEntity processDefinition) {
ActivityImpl activity = processDefinition.findActivity(key);
if (activity != null) {
createDIBounds(graphicInfo, activity);
} else {
org.activiti.engine.impl.pvm.process.Lane lane = processDefinition.getLaneForId(key);
if(lane != null) {
// The shape represents a lane
createDIBounds(graphicInfo, lane);
} else {
bpmnModel.addProblem("Invalid reference in 'bpmnElement' attribute, activity " + key + " not found", graphicInfo);
}
}
}
protected void createDIBounds(GraphicInfo graphicInfo, HasDIBounds target) {
target.setX((int) graphicInfo.getX());
target.setY((int) graphicInfo.getY());
target.setWidth((int) graphicInfo.getWidth());
target.setHeight((int) graphicInfo.getHeight());
protected void createDIBounds(GraphicInfo graphicInfo, HasDIBounds target) {
target.setX((int) graphicInfo.getX());
target.setY((int) graphicInfo.getY());
target.setWidth((int) graphicInfo.getWidth());
target.setHeight((int) graphicInfo.getHeight());
}
public void createBPMNEdge(String key, List<GraphicInfo> graphicList) {
......@@ -2223,11 +656,19 @@ public class BpmnParse implements BpmnXMLConstants {
// Getters, setters and Parser overriden operations
// ////////////////////////////////////////
public List<ProcessDefinitionEntity> getProcessDefinitions() {
return processDefinitions;
}
public BpmnParseHandlers getBpmnParserHandlers() {
return bpmnParserHandlers;
}
public void setBpmnParserHandlers(BpmnParseHandlers bpmnParserHandlers) {
this.bpmnParserHandlers = bpmnParserHandlers;
}
public ProcessDefinitionEntity getProcessDefinition(String processDefinitionKey) {
for (ProcessDefinitionEntity processDefinition : processDefinitions) {
if (processDefinition.getKey().equals(processDefinitionKey)) {
......@@ -2249,6 +690,22 @@ public class BpmnParse implements BpmnXMLConstants {
this.operationImplementations.put(operationImplementation.getId(), operationImplementation);
}
public DeploymentEntity getDeployment() {
return deployment;
}
public void setDeployment(DeploymentEntity deployment) {
this.deployment = deployment;
}
public BpmnModel getBpmnModel() {
return bpmnModel;
}
public void setBpmnModel(BpmnModel bpmnModel) {
this.bpmnModel = bpmnModel;
}
public ActivityBehaviorFactory getActivityBehaviorFactory() {
return activityBehaviorFactory;
}
......@@ -2264,5 +721,77 @@ public class BpmnParse implements BpmnXMLConstants {
public void setListenerFactory(ListenerFactory listenerFactory) {
this.listenerFactory = listenerFactory;
}
public ExpressionManager getExpressionManager() {
return expressionManager;
}
public void setExpressionManager(ExpressionManager expressionManager) {
this.expressionManager = expressionManager;
}
public Map<String, TransitionImpl> getSequenceFlows() {
return sequenceFlows;
}
public void setSequenceFlows(Map<String, TransitionImpl> sequenceFlows) {
this.sequenceFlows = sequenceFlows;
}
public Map<String, Operation> getOperations() {
return operations;
}
public void setOperations(Map<String, Operation> operations) {
this.operations = operations;
}
public ProcessDefinitionEntity getCurrentProcessDefinition() {
return currentProcessDefinition;
}
public void setCurrentProcessDefinition(ProcessDefinitionEntity currentProcessDefinition) {
this.currentProcessDefinition = currentProcessDefinition;
}
public FlowElement getCurrentFlowElement() {
return currentFlowElement;
}
public void setCurrentFlowElement(FlowElement currentFlowElement) {
this.currentFlowElement = currentFlowElement;
}
public ActivityImpl getCurrentActivity() {
return currentActivity;
}
public void setCurrentActivity(ActivityImpl currentActivity) {
this.currentActivity = currentActivity;
}
public void setCurrentSubProcess(SubProcess subProcess) {
currentSubprocessStack.push(subProcess);
}
public SubProcess getCurrentSubProcess() {
return currentSubprocessStack.peek();
}
public void removeCurrentSubProcess() {
currentSubprocessStack.pop();
}
public void setCurrentScope(ScopeImpl scope) {
currentScopeStack.push(scope);
}
public ScopeImpl getCurrentScope() {
return currentScopeStack.peek();
}
public void removeCurrentScope() {
currentScopeStack.pop();
}
}
/* 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.impl.bpmn.parser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.engine.parse.BpmnParseHandler;
import org.slf4j.Logger;
/**
* @author Joram Barrez
*/
public class BpmnParseHandlers {
private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(BpmnParseHandlers.class);
protected Map<Class<? extends BaseElement>, List<BpmnParseHandler>> parseHandlers;
public BpmnParseHandlers() {
this.parseHandlers = new HashMap<Class<? extends BaseElement>, List<BpmnParseHandler>>();
}
public List<BpmnParseHandler> getHandlersFor(Class<? extends BaseElement> clazz) {
return parseHandlers.get(clazz);
}
public void addHandlers(List<BpmnParseHandler> bpmnParseHandlers) {
for (BpmnParseHandler bpmnParseHandler : bpmnParseHandlers) {
addHandler(bpmnParseHandler);
}
}
public void addHandler(BpmnParseHandler bpmnParseHandler) {
for (Class<? extends BaseElement> type : bpmnParseHandler.getHandledTypes()) {
List<BpmnParseHandler> handlers = parseHandlers.get(type);
if (handlers == null) {
handlers = new ArrayList<BpmnParseHandler>();
parseHandlers.put(type, handlers);
}
handlers.add(bpmnParseHandler);
}
}
public void parse(BpmnParse bpmnParse, BaseElement element) {
if (element instanceof FlowElement) {
bpmnParse.setCurrentFlowElement((FlowElement) element);
}
// Execute parse handlers
List<BpmnParseHandler> handlers = parseHandlers.get(element.getClass());
if (handlers == null) {
LOGGER.warn("Could not find matching parse handler for + " + element.getId() + " this is likely a bug.");
} else {
for (BpmnParseHandler handler : handlers) {
handler.parse(bpmnParse, element);
}
}
}
}
......@@ -12,10 +12,6 @@
*/
package org.activiti.engine.impl.bpmn.parser;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.BpmnParseListener;
import org.activiti.engine.impl.bpmn.parser.factory.ActivityBehaviorFactory;
import org.activiti.engine.impl.bpmn.parser.factory.ListenerFactory;
import org.activiti.engine.impl.cfg.BpmnParseFactory;
......@@ -74,7 +70,7 @@ public class BpmnParser extends Parser {
protected ActivityBehaviorFactory activityBehaviorFactory;
protected ListenerFactory listenerFactory;
protected BpmnParseFactory bpmnParseFactory;
protected List<BpmnParseListener> parseListeners = new ArrayList<BpmnParseListener>();
protected BpmnParseHandlers bpmnParserHandlers;
/**
* Creates a new {@link BpmnParse} instance that can be used
......@@ -116,11 +112,12 @@ public class BpmnParser extends Parser {
this.expressionManager = expressionManager;
}
public List<BpmnParseListener> getParseListeners() {
return parseListeners;
public BpmnParseHandlers getBpmnParserHandlers() {
return bpmnParserHandlers;
}
public void setParseListeners(List<BpmnParseListener> parseListeners) {
this.parseListeners = parseListeners;
public void setBpmnParserHandlers(BpmnParseHandlers bpmnParserHandlers) {
this.bpmnParserHandlers = bpmnParserHandlers;
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public abstract class AbstractActivityBpmnParseHandler<T extends FlowNode> extends AbstractFlowNodeBpmnParseHandler<T> {
@Override
public void parse(BpmnParse bpmnParse, BaseElement element) {
super.parse(bpmnParse, element);
if (element instanceof Activity
&& ((Activity) element).getLoopCharacteristics() != null) {
createMultiInstanceLoopCharacteristics(bpmnParse, (Activity) element);
}
}
protected void createMultiInstanceLoopCharacteristics(BpmnParse bpmnParse, org.activiti.bpmn.model.Activity modelActivity) {
MultiInstanceLoopCharacteristics loopCharacteristics = modelActivity.getLoopCharacteristics();
// Activity Behavior
MultiInstanceActivityBehavior miActivityBehavior = null;
ActivityImpl activity = bpmnParse.getCurrentScope().findActivity(modelActivity.getId());
if (activity == null) {
bpmnParse.getBpmnModel().addProblem("Activity " + modelActivity.getId() + " needed for multi instance cannot bv found", modelActivity);
}
if (loopCharacteristics.isSequential()) {
miActivityBehavior = bpmnParse.getActivityBehaviorFactory().createSequentialMultiInstanceBehavior(
activity, (AbstractBpmnActivityBehavior) activity.getActivityBehavior());
} else {
miActivityBehavior = bpmnParse.getActivityBehaviorFactory().createParallelMultiInstanceBehavior(
activity, (AbstractBpmnActivityBehavior) activity.getActivityBehavior());
}
// ActivityImpl settings
activity.setScope(true);
activity.setProperty("multiInstance", loopCharacteristics.isSequential() ? "sequential" : "parallel");
activity.setActivityBehavior(miActivityBehavior);
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
// loopcardinality
if (StringUtils.isNotEmpty(loopCharacteristics.getLoopCardinality())) {
miActivityBehavior.setLoopCardinalityExpression(expressionManager.createExpression(loopCharacteristics.getLoopCardinality()));
}
// completion condition
if (StringUtils.isNotEmpty(loopCharacteristics.getCompletionCondition())) {
miActivityBehavior.setCompletionConditionExpression(expressionManager.createExpression(loopCharacteristics.getCompletionCondition()));
}
// activiti:collection
if (StringUtils.isNotEmpty(loopCharacteristics.getInputDataItem())) {
if (loopCharacteristics.getInputDataItem().contains("{")) {
miActivityBehavior.setCollectionExpression(expressionManager.createExpression(loopCharacteristics.getInputDataItem()));
} else {
miActivityBehavior.setCollectionVariable(loopCharacteristics.getInputDataItem());
}
}
// activiti:elementVariable
if (StringUtils.isNotEmpty(loopCharacteristics.getElementVariable())) {
miActivityBehavior.setCollectionElementVariable(loopCharacteristics.getElementVariable());
}
// Validation
if (miActivityBehavior.getLoopCardinalityExpression() == null && miActivityBehavior.getCollectionExpression() == null
&& miActivityBehavior.getCollectionVariable() == null) {
bpmnModel.addProblem("Either loopCardinality or loopDataInputRef/activiti:collection must been set.", loopCharacteristics);
}
// Validation
if (miActivityBehavior.getCollectionExpression() == null && miActivityBehavior.getCollectionVariable() == null
&& miActivityBehavior.getCollectionElementVariable() != null) {
bpmnModel.addProblem("LoopDataInputRef/activiti:collection must be set when using inputDataItem or activiti:elementVariable.", loopCharacteristics);
}
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.activiti.bpmn.model.ActivitiListener;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Gateway;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.EventSubscriptionDeclaration;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.parse.BpmnParseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Doccen: do not use, only for internal usage
* (or we must extract a second subclass).
*
* @author Joram Barrez
*/
public abstract class AbstractBpmnParseHandler<T extends BaseElement> implements BpmnParseHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractBpmnParseHandler.class);
public static final String PROPERTYNAME_IS_FOR_COMPENSATION = "isForCompensation";
public static final String PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION = "eventDefinitions";
public static final String PROPERTYNAME_ERROR_EVENT_DEFINITIONS = "errorEventDefinitions";
public static final String PROPERTYNAME_TIMER_DECLARATION = "timerDeclarations";
public Set<Class< ? extends BaseElement>> getHandledTypes() {
Set<Class< ? extends BaseElement>> types = new HashSet<Class<? extends BaseElement>>();
types.add(getHandledType());
return types;
}
protected Class<? extends BaseElement> getHandledType() {
// Subclasses should override
return null;
}
@SuppressWarnings("unchecked")
public void parse(BpmnParse bpmnParse, BaseElement element) {
T baseElement = (T) element;
executeParse(bpmnParse, baseElement);
}
protected abstract void executeParse(BpmnParse bpmnParse, T element);
protected ActivityImpl findActivity(BpmnParse bpmnParse, String id) {
return bpmnParse.getCurrentScope().findActivity(id);
}
public ActivityImpl createActivityOnCurrentScope(BpmnParse bpmnParse, FlowElement flowElement, String xmlLocalName) {
return createActivityOnScope(bpmnParse, flowElement, xmlLocalName, bpmnParse.getCurrentScope());
}
public ActivityImpl createActivityOnScope(BpmnParse bpmnParse, FlowElement flowElement, String xmlLocalName, ScopeImpl scopeElement) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing activity {}", flowElement.getId());
}
ActivityImpl activity = scopeElement.createActivity(flowElement.getId());
bpmnParse.setCurrentActivity(activity);
activity.setProperty("name", flowElement.getName());
activity.setProperty("documentation", flowElement.getDocumentation());
if (flowElement instanceof Activity) {
Activity modelActivity = (Activity) flowElement;
activity.setProperty("default", modelActivity.getDefaultFlow());
if(modelActivity.isForCompensation()) {
activity.setProperty(PROPERTYNAME_IS_FOR_COMPENSATION, true);
}
} else if (flowElement instanceof Gateway) {
activity.setProperty("default", ((Gateway) flowElement).getDefaultFlow());
}
activity.setProperty("type", xmlLocalName);
return activity;
}
protected void createExecutionListenersOnScope(BpmnParse bpmnParse, List<ActivitiListener> activitiListenerList, ScopeImpl scope) {
for (ActivitiListener activitiListener : activitiListenerList) {
scope.addExecutionListener(activitiListener.getEvent(), createExecutionListener(bpmnParse, activitiListener));
}
}
protected void createExecutionListenersOnTransition(BpmnParse bpmnParse, List<ActivitiListener> activitiListenerList, TransitionImpl transition) {
for (ActivitiListener activitiListener : activitiListenerList) {
transition.addExecutionListener(createExecutionListener(bpmnParse, activitiListener));
}
}
protected ExecutionListener createExecutionListener(BpmnParse bpmnParse, ActivitiListener activitiListener) {
ExecutionListener executionListener = null;
if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = bpmnParse.getListenerFactory().createClassDelegateExecutionListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = bpmnParse.getListenerFactory().createExpressionExecutionListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
executionListener = bpmnParse.getListenerFactory().createDelegateExpressionExecutionListener(activitiListener);
}
return executionListener;
}
@SuppressWarnings("unchecked")
protected void addEventSubscriptionDeclaration(BpmnParse bpmnParse, EventSubscriptionDeclaration subscription, EventDefinition parsedEventDefinition, ScopeImpl scope) {
List<EventSubscriptionDeclaration> eventDefinitions = (List<EventSubscriptionDeclaration>) scope.getProperty(PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION);
if(eventDefinitions == null) {
eventDefinitions = new ArrayList<EventSubscriptionDeclaration>();
scope.setProperty(PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION, eventDefinitions);
} else {
// if this is a message event, validate that it is the only one with the provided name for this scope
if(subscription.getEventType().equals("message")) {
for (EventSubscriptionDeclaration eventDefinition : eventDefinitions) {
if(eventDefinition.getEventType().equals("message")
&& eventDefinition.getEventName().equals(subscription.getEventName())
&& eventDefinition.isStartEvent() == subscription.isStartEvent()) {
bpmnParse.getBpmnModel().addProblem("Cannot have more than one message event subscription with name '" + subscription.getEventName() +
"' for scope '"+scope.getId()+"'", parsedEventDefinition);
}
}
}
}
eventDefinitions.add(subscription);
}
protected String getPrecedingEventBasedGateway(BpmnParse bpmnParse, IntermediateCatchEvent event) {
String eventBasedGatewayId = null;
for (SequenceFlow sequenceFlow : event.getIncomingFlows()) {
FlowElement sourceElement = bpmnParse.getBpmnModel().getFlowElement(sequenceFlow.getSourceRef());
if (sourceElement instanceof EventGateway) {
eventBasedGatewayId = sourceElement.getId();
break;
}
}
return eventBasedGatewayId;
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.List;
import org.activiti.bpmn.model.FieldExtension;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Task;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
/**
* @author Joram Barrez
*/
public abstract class AbstractExternalInvocationBpmnParseHandler<T extends FlowNode> extends AbstractActivityBpmnParseHandler<T> {
protected void validateFieldDeclarationsForEmail(BpmnParse bpmnParse, Task task, List<FieldExtension> fieldExtensions) {
boolean toDefined = false;
boolean textOrHtmlDefined = false;
for (FieldExtension fieldExtension : fieldExtensions) {
if (fieldExtension.getFieldName().equals("to")) {
toDefined = true;
}
if (fieldExtension.getFieldName().equals("html")) {
textOrHtmlDefined = true;
}
if (fieldExtension.getFieldName().equals("text")) {
textOrHtmlDefined = true;
}
}
if (!toDefined) {
bpmnParse.getBpmnModel().addProblem("No recipient is defined on the mail activity", task);
}
if (!textOrHtmlDefined) {
bpmnParse.getBpmnModel().addProblem("Text or html field should be provided", task);
}
}
protected void validateFieldDeclarationsForShell(BpmnParse bpmnParse, Task task, List<FieldExtension> fieldExtensions) {
boolean shellCommandDefined = false;
for (FieldExtension fieldExtension : fieldExtensions) {
String fieldName = fieldExtension.getFieldName();
String fieldValue = fieldExtension.getStringValue();
shellCommandDefined |= fieldName.equals("command");
if ((fieldName.equals("wait") || fieldName.equals("redirectError") || fieldName.equals("cleanEnv")) && !fieldValue.toLowerCase().equals("true")
&& !fieldValue.toLowerCase().equals("false")) {
bpmnParse.getBpmnModel().addProblem("undefined value for shell " + fieldName + " parameter :" + fieldValue.toString() + ".", task);
}
}
if (!shellCommandDefined) {
bpmnParse.getBpmnModel().addProblem("No shell command is defined on the shell activity", task);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
/**
* @author Joram Barrez
*/
public abstract class AbstractFlowNodeBpmnParseHandler<T extends FlowNode> extends AbstractBpmnParseHandler<T> {
@Override
public void parse(BpmnParse bpmnParse, BaseElement element) {
super.parse(bpmnParse, element);
createExecutionListenersOnScope(bpmnParse, ((FlowNode) element).getExecutionListeners(), findActivity(bpmnParse, element.getId()));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.CancelEventDefinition;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class BoundaryEventParseHandler extends AbstractBpmnParseHandler<BoundaryEvent> {
public Class< ? extends BaseElement> getHandledType() {
return BoundaryEvent.class;
}
protected void executeParse(BpmnParse bpmnParse, BoundaryEvent boundaryEvent) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
ActivityImpl parentActivity = findActivity(bpmnParse, boundaryEvent.getAttachedToRefId());
if (parentActivity == null) {
bpmnModel.addProblem("Invalid reference in boundary event. Make sure that the referenced activity is defined in the same scope as the boundary event", boundaryEvent);
return;
}
ActivityImpl nestedActivity = createActivityOnScope(bpmnParse, boundaryEvent, BpmnXMLConstants.ELEMENT_EVENT_BOUNDARY, parentActivity);
bpmnParse.setCurrentActivity(nestedActivity);
EventDefinition eventDefinition = null;
if (boundaryEvent.getEventDefinitions().size() > 0) {
eventDefinition = boundaryEvent.getEventDefinitions().get(0);
}
if (eventDefinition instanceof TimerEventDefinition
|| eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition
|| eventDefinition instanceof SignalEventDefinition
|| eventDefinition instanceof CancelEventDefinition
|| eventDefinition instanceof MessageEventDefinition
|| eventDefinition instanceof org.activiti.bpmn.model.CompensateEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else {
bpmnModel.addProblem("Unsupported boundary event type", boundaryEvent);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class BusinessRuleParseHandler extends AbstractActivityBpmnParseHandler<BusinessRuleTask> {
public Class< ? extends BaseElement> getHandledType() {
return BusinessRuleTask.class;
}
@Override
protected void executeParse(BpmnParse bpmnParse, BusinessRuleTask businessRuleTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, businessRuleTask, BpmnXMLConstants.ELEMENT_TASK_BUSINESSRULE);
activity.setAsync(businessRuleTask.isAsynchronous());
activity.setExclusive(!businessRuleTask.isNotExclusive());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createBusinessRuleTaskActivityBehavior(businessRuleTask));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class CallActivityParseHandler extends AbstractActivityBpmnParseHandler<CallActivity> {
public Class< ? extends BaseElement> getHandledType() {
return CallActivity.class;
}
protected void executeParse(BpmnParse bpmnParse, CallActivity callActivity) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, callActivity, BpmnXMLConstants.ELEMENT_CALL_ACTIVITY);
activity.setScope(true);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createCallActivityBehavior(callActivity));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.CancelEventDefinition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class CancelEventDefinitionParseHandler extends AbstractBpmnParseHandler<CancelEventDefinition> {
public Class< ? extends BaseElement> getHandledType() {
return CancelEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, CancelEventDefinition cancelEventDefinition) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
ActivityImpl activity = bpmnParse.getCurrentActivity();
activity.setProperty("type", "cancelBoundaryCatch");
ActivityImpl parent = (ActivityImpl) activity.getParent();
if (!parent.getProperty("type").equals("transaction")) {
bpmnModel.addProblem("boundary event with cancelEventDefinition only supported on transaction subprocesses.", cancelEventDefinition);
}
for (ActivityImpl child : parent.getActivities()) {
if (child.getProperty("type").equals("cancelBoundaryCatch") && child != activity) {
bpmnModel.addProblem("multiple boundary events with cancelEventDefinition not supported on same transaction subprocess.", cancelEventDefinition);
}
}
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createCancelBoundaryEventActivityBehavior(cancelEventDefinition));
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.CompensateEventDefinition;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class CompensateEventDefinitionParseHandler extends AbstractBpmnParseHandler<CompensateEventDefinition> {
public Class< ? extends BaseElement> getHandledType() {
return CompensateEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, CompensateEventDefinition eventDefinition) {
ScopeImpl scope = bpmnParse.getCurrentScope();
if(StringUtils.isNotEmpty(eventDefinition.getActivityRef())) {
if(scope.findActivity(eventDefinition.getActivityRef()) == null) {
bpmnParse.getBpmnModel().addProblem("Invalid attribute value for 'activityRef': no activity with id '" + eventDefinition.getActivityRef() +
"' in current scope " + scope.getId(), eventDefinition);
}
}
org.activiti.engine.impl.bpmn.parser.CompensateEventDefinition compensateEventDefinition =
new org.activiti.engine.impl.bpmn.parser.CompensateEventDefinition();
compensateEventDefinition.setActivityRef(eventDefinition.getActivityRef());
compensateEventDefinition.setWaitForCompletion(eventDefinition.isWaitForCompletion());
ActivityImpl activity = bpmnParse.getCurrentActivity();
if (bpmnParse.getCurrentFlowElement() instanceof ThrowEvent) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createIntermediateThrowCompensationEventActivityBehavior((ThrowEvent) bpmnParse.getCurrentFlowElement(), compensateEventDefinition));
} else if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
BoundaryEvent boundaryEvent = (BoundaryEvent) bpmnParse.getCurrentFlowElement();
boolean interrupting = boundaryEvent.isCancelActivity();
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createBoundaryEventActivityBehavior(boundaryEvent, interrupting, activity));
activity.setProperty("type", "compensationBoundaryCatch");
ScopeImpl parent = activity.getParent();
for (ActivityImpl child : parent.getActivities()) {
if (child.getProperty("type").equals("compensationBoundaryCatch") && child != activity ) {
bpmnParse.getBpmnModel().addProblem("multiple boundary events with compensateEventDefinition not supported on same activity.", eventDefinition);
}
}
} else {
// What to do?
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.CancelEventDefinition;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.TerminateEventDefinition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class EndEventParseHandler extends AbstractActivityBpmnParseHandler<EndEvent> {
public Class< ? extends BaseElement> getHandledType() {
return EndEvent.class;
}
protected void executeParse(BpmnParse bpmnParse, EndEvent endEvent) {
ActivityImpl endEventActivity = createActivityOnCurrentScope(bpmnParse, endEvent, BpmnXMLConstants.ELEMENT_EVENT_END);
EventDefinition eventDefinition = null;
if (endEvent.getEventDefinitions().size() > 0) {
eventDefinition = endEvent.getEventDefinitions().get(0);
}
// Error end event
if (eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition) {
org.activiti.bpmn.model.ErrorEventDefinition errorDefinition = (org.activiti.bpmn.model.ErrorEventDefinition) eventDefinition;
if (bpmnParse.getBpmnModel().containsErrorRef(errorDefinition.getErrorCode())) {
String errorCode = bpmnParse.getBpmnModel().getErrors().get(errorDefinition.getErrorCode());
if (StringUtils.isEmpty(errorCode)) {
bpmnParse.getBpmnModel().addProblem("errorCode is required for an error event", errorDefinition);
}
endEventActivity.setProperty("type", "errorEndEvent");
errorDefinition.setErrorCode(errorCode);
}
endEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createErrorEndEventActivityBehavior(endEvent, errorDefinition));
// Cancel end event
} else if (eventDefinition instanceof CancelEventDefinition) {
ScopeImpl scope = bpmnParse.getCurrentScope();
if (scope.getProperty("type")==null || !scope.getProperty("type").equals("transaction")) {
bpmnParse.getBpmnModel().addProblem("end event with cancelEventDefinition only supported inside transaction subprocess", endEvent);
} else {
endEventActivity.setProperty("type", "cancelEndEvent");
endEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createCancelEndEventActivityBehavior(endEvent));
}
// Terminate end event
} else if (eventDefinition instanceof TerminateEventDefinition) {
endEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createTerminateEndEventActivityBehavior(endEvent));
// None end event
} else if (eventDefinition == null) {
endEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createNoneEndEventActivityBehavior(endEvent));
}
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class ErrorEventDefinitionParseHandler extends AbstractBpmnParseHandler<ErrorEventDefinition> {
public static final String PROPERTYNAME_INITIAL = "initial";
public Class< ? extends BaseElement> getHandledType() {
return ErrorEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, ErrorEventDefinition eventDefinition) {
org.activiti.bpmn.model.ErrorEventDefinition modelErrorEvent = (org.activiti.bpmn.model.ErrorEventDefinition) eventDefinition;
if (bpmnParse.getBpmnModel().containsErrorRef(modelErrorEvent.getErrorCode())) {
String errorCode = bpmnParse.getBpmnModel().getErrors().get(modelErrorEvent.getErrorCode());
if (StringUtils.isEmpty(errorCode)) {
bpmnParse.getBpmnModel().addProblem("errorCode is required for an error event", eventDefinition);
}
modelErrorEvent.setErrorCode(errorCode);
}
ScopeImpl scope = bpmnParse.getCurrentScope();
ActivityImpl activity = bpmnParse.getCurrentActivity();
if (bpmnParse.getCurrentFlowElement() instanceof StartEvent) {
if (scope.getProperty(PROPERTYNAME_INITIAL) == null) {
scope.setProperty(PROPERTYNAME_INITIAL, activity);
// the scope of the event subscription is the parent of the event
// subprocess (subscription must be created when parent is initialized)
ScopeImpl catchingScope = ((ActivityImpl) scope).getParent();
createErrorStartEventDefinition(modelErrorEvent, activity, catchingScope);
} else {
bpmnParse.getBpmnModel().addProblem("multiple start events not supported for subprocess", bpmnParse.getCurrentSubProcess());
}
} else if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
BoundaryEvent boundaryEvent = (BoundaryEvent) bpmnParse.getCurrentFlowElement();
boolean interrupting = true; // non-interrupting not yet supported
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createBoundaryEventActivityBehavior(boundaryEvent, interrupting, activity));
ActivityImpl parentActivity = scope.findActivity(boundaryEvent.getAttachedToRefId());
createBoundaryErrorEventDefinition(modelErrorEvent, interrupting, parentActivity, activity);
}
}
protected void createErrorStartEventDefinition(org.activiti.bpmn.model.ErrorEventDefinition errorEventDefinition, ActivityImpl startEventActivity, ScopeImpl scope) {
org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition definition = new org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition(startEventActivity.getId());
if (StringUtils.isNotEmpty(errorEventDefinition.getErrorCode())) {
definition.setErrorCode(errorEventDefinition.getErrorCode());
}
definition.setPrecedence(10);
addErrorEventDefinition(definition, scope);
}
public void createBoundaryErrorEventDefinition(org.activiti.bpmn.model.ErrorEventDefinition errorEventDefinition, boolean interrupting,
ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
nestedErrorEventActivity.setProperty("type", "boundaryError");
ScopeImpl catchingScope = nestedErrorEventActivity.getParent();
((ActivityImpl) catchingScope).setScope(true);
org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition definition =
new org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition(nestedErrorEventActivity.getId());
definition.setErrorCode(errorEventDefinition.getErrorCode());
addErrorEventDefinition(definition, catchingScope);
}
@SuppressWarnings("unchecked")
protected void addErrorEventDefinition(org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition errorEventDefinition, ScopeImpl catchingScope) {
List<org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition> errorEventDefinitions =
(List<org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition>) catchingScope.getProperty(PROPERTYNAME_ERROR_EVENT_DEFINITIONS);
if(errorEventDefinitions == null) {
errorEventDefinitions = new ArrayList<org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition>();
catchingScope.setProperty(PROPERTYNAME_ERROR_EVENT_DEFINITIONS, errorEventDefinitions);
}
errorEventDefinitions.add(errorEventDefinition);
Collections.sort(errorEventDefinitions, org.activiti.engine.impl.bpmn.parser.ErrorEventDefinition.comparator);
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class EventBasedGatewayParseHandler extends AbstractActivityBpmnParseHandler<EventGateway> {
public Class< ? extends BaseElement> getHandledType() {
return EventGateway.class;
}
protected void executeParse(BpmnParse bpmnParse, EventGateway gateway) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, gateway, BpmnXMLConstants.ELEMENT_GATEWAY_EVENT);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createEventBasedGatewayActivityBehavior(gateway));
activity.setScope(true);
// find all outgoing sequence flows
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
for (SequenceFlow sequenceFlow : gateway.getOutgoingFlows()) {
FlowElement flowElement = bpmnModel.getFlowElement(sequenceFlow.getTargetRef());
if (flowElement != null && flowElement instanceof IntermediateCatchEvent == false) {
bpmnModel.addProblem("Event based gateway can only be connected to elements of type intermediateCatchEvent.", flowElement);
}
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class ExclusiveGatewayParseHandler extends AbstractActivityBpmnParseHandler<ExclusiveGateway> {
public Class< ? extends BaseElement> getHandledType() {
return ExclusiveGateway.class;
}
protected void executeParse(BpmnParse bpmnParse, ExclusiveGateway gateway) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, gateway, BpmnXMLConstants.ELEMENT_GATEWAY_EXCLUSIVE);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createExclusiveGatewayActivityBehavior(gateway));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class InclusiveGatewayParseHandler extends AbstractActivityBpmnParseHandler<InclusiveGateway> {
public Class< ? extends BaseElement> getHandledType() {
return InclusiveGateway.class;
}
protected void executeParse(BpmnParse bpmnParse, InclusiveGateway gateway) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, gateway, BpmnXMLConstants.ELEMENT_GATEWAY_INCLUSIVE);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createInclusiveGatewayActivityBehavior(gateway));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
/**
* @author Joram Barrez
*/
public class IntermediateCatchEventParseHandler extends AbstractActivityBpmnParseHandler<IntermediateCatchEvent> {
public Class< ? extends BaseElement> getHandledType() {
return IntermediateCatchEvent.class;
}
protected void executeParse(BpmnParse bpmnParse, IntermediateCatchEvent event) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
ActivityImpl nestedActivity = null;
EventDefinition eventDefinition = null;
if (event.getEventDefinitions().size() > 0) {
eventDefinition = event.getEventDefinitions().get(0);
}
if (eventDefinition == null) {
bpmnModel.addProblem("No event definition for intermediate catch event " + event.getId(), event);
nestedActivity = createActivityOnCurrentScope(bpmnParse, event, BpmnXMLConstants.ELEMENT_EVENT_CATCH);
} else {
ScopeImpl scope = bpmnParse.getCurrentScope();
String eventBasedGatewayId = getPrecedingEventBasedGateway(bpmnParse, event);
if (eventBasedGatewayId != null) {
ActivityImpl gatewayActivity = scope.findActivity(eventBasedGatewayId);
nestedActivity = createActivityOnScope(bpmnParse, event, BpmnXMLConstants.ELEMENT_EVENT_CATCH, gatewayActivity);
} else {
nestedActivity = createActivityOnScope(bpmnParse, event, BpmnXMLConstants.ELEMENT_EVENT_CATCH, scope);
}
// Catch event behavior is the same for all types
nestedActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createIntermediateCatchEventActivityBehavior(event));
if (eventDefinition instanceof TimerEventDefinition
|| eventDefinition instanceof SignalEventDefinition
|| eventDefinition instanceof MessageEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else {
bpmnModel.addProblem("Unsupported intermediate catch event type.", event);
}
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.CompensateEventDefinition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class IntermediateThrowEventParseHandler extends AbstractActivityBpmnParseHandler<ThrowEvent> {
public Class< ? extends BaseElement> getHandledType() {
return ThrowEvent.class;
}
protected void executeParse(BpmnParse bpmnParse, ThrowEvent intermediateEvent) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
ActivityImpl nestedActivityImpl = createActivityOnCurrentScope(bpmnParse, intermediateEvent, BpmnXMLConstants.ELEMENT_EVENT_THROW);
EventDefinition eventDefinition = null;
if (intermediateEvent.getEventDefinitions().size() > 0) {
eventDefinition = intermediateEvent.getEventDefinitions().get(0);
}
if (eventDefinition instanceof SignalEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else if (eventDefinition instanceof org.activiti.bpmn.model.CompensateEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else if (eventDefinition == null) {
nestedActivityImpl.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createIntermediateThrowNoneEventActivityBehavior(intermediateEvent));
} else {
bpmnModel.addProblem("Unsupported intermediate throw event type " + eventDefinition, intermediateEvent);
}
}
protected CompensateEventDefinition createCompensateEventDefinition(BpmnParse bpmnParse, org.activiti.bpmn.model.CompensateEventDefinition eventDefinition, ScopeImpl scopeElement) {
if(StringUtils.isNotEmpty(eventDefinition.getActivityRef())) {
if(scopeElement.findActivity(eventDefinition.getActivityRef()) == null) {
bpmnParse.getBpmnModel().addProblem("Invalid attribute value for 'activityRef': no activity with id '" + eventDefinition.getActivityRef() +
"' in current scope " + scopeElement.getId(), eventDefinition);
}
}
CompensateEventDefinition compensateEventDefinition = new CompensateEventDefinition();
compensateEventDefinition.setActivityRef(eventDefinition.getActivityRef());
compensateEventDefinition.setWaitForCompletion(eventDefinition.isWaitForCompletion());
return compensateEventDefinition;
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class ManualTaskParseHandler extends AbstractActivityBpmnParseHandler<ManualTask> {
public Class< ? extends BaseElement> getHandledType() {
return ManualTask.class;
}
protected void executeParse(BpmnParse bpmnParse, ManualTask manualTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, manualTask, BpmnXMLConstants.ELEMENT_TASK_MANUAL);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createManualTaskActivityBehavior(manualTask));
activity.setAsync(manualTask.isAsynchronous());
activity.setExclusive(!manualTask.isNotExclusive());
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.EventSubscriptionDeclaration;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class MessageEventDefinitionParseHandler extends AbstractBpmnParseHandler<MessageEventDefinition> {
public Class< ? extends BaseElement> getHandledType() {
return MessageEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, MessageEventDefinition messageDefinition) {
if (bpmnParse.getBpmnModel().containsMessageId(messageDefinition.getMessageRef())) {
String messageName = bpmnParse.getBpmnModel().getMessage(messageDefinition.getMessageRef()).getName();
if (StringUtils.isEmpty(messageName)) {
bpmnParse.getBpmnModel().addProblem("messageName is required for a message event", messageDefinition);
}
messageDefinition.setMessageRef(messageName);
}
EventSubscriptionDeclaration eventSubscription = new EventSubscriptionDeclaration(messageDefinition.getMessageRef(), "message");
ScopeImpl scope = bpmnParse.getCurrentScope();
ActivityImpl activity = bpmnParse.getCurrentActivity();
if (bpmnParse.getCurrentFlowElement() instanceof StartEvent && bpmnParse.getCurrentSubProcess() != null) {
// the scope of the event subscription is the parent of the event
// subprocess (subscription must be created when parent is initialized)
ScopeImpl catchingScope = ((ActivityImpl) scope).getParent();
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(messageDefinition.getMessageRef(), "message");
eventSubscriptionDeclaration.setActivityId(activity.getId());
eventSubscriptionDeclaration.setStartEvent(false);
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, messageDefinition, catchingScope);
} else if (bpmnParse.getCurrentFlowElement() instanceof StartEvent) {
activity.setProperty("type", "messageStartEvent");
eventSubscription.setStartEvent(true);
eventSubscription.setActivityId(activity.getId());
addEventSubscriptionDeclaration(bpmnParse, eventSubscription, messageDefinition, bpmnParse.getCurrentProcessDefinition());
} else if (bpmnParse.getCurrentFlowElement() instanceof IntermediateCatchEvent) {
activity.setProperty("type", "intermediateMessageCatch");
if(getPrecedingEventBasedGateway(bpmnParse, (IntermediateCatchEvent) bpmnParse.getCurrentFlowElement()) != null) {
eventSubscription.setActivityId(activity.getId());
addEventSubscriptionDeclaration(bpmnParse, eventSubscription, messageDefinition, activity.getParent());
} else {
activity.setScope(true);
addEventSubscriptionDeclaration(bpmnParse, eventSubscription, messageDefinition, activity);
}
} else if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
BoundaryEvent boundaryEvent = (BoundaryEvent) bpmnParse.getCurrentFlowElement();
boolean interrupting = boundaryEvent.isCancelActivity();
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createBoundaryEventActivityBehavior(boundaryEvent, interrupting, activity));
activity.setProperty("type", "boundaryMessage");
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(messageDefinition.getMessageRef(), "message");
eventSubscriptionDeclaration.setActivityId(activity.getId());
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, messageDefinition, activity.getParent());
if (activity.getParent() instanceof ActivityImpl) {
((ActivityImpl) activity.getParent()).setScope(true);
}
}
else {
// What to do here?
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class ParallelGatewayParseHandler extends AbstractActivityBpmnParseHandler<ParallelGateway> {
public Class< ? extends BaseElement> getHandledType() {
return ParallelGateway.class;
}
protected void executeParse(BpmnParse bpmnParse, ParallelGateway gateway) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, gateway, BpmnXMLConstants.ELEMENT_GATEWAY_PARALLEL);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createParallelGatewayActivityBehavior(gateway));
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.HashMap;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.task.TaskDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Joram Barrez
*/
public class ProcessParseHandler extends AbstractBpmnParseHandler<Process> {
private static final Logger LOGGER = LoggerFactory.getLogger(ProcessParseHandler.class);
public static final String PROPERTYNAME_DOCUMENTATION = "documentation";
public Class< ? extends BaseElement> getHandledType() {
return Process.class;
}
protected void executeParse(BpmnParse bpmnParse, Process process) {
if (process.isExecutable() == false) {
LOGGER.info("Ignoring non-executable process with id='" + process.getId() + "'. Set the attribute isExecutable=\"true\" to deploy this process.");
} else {
bpmnParse.getProcessDefinitions().add(transformProcess(bpmnParse, process));
}
}
protected ProcessDefinitionEntity transformProcess(BpmnParse bpmnParse, Process process) {
ProcessDefinitionEntity currentProcessDefinition = new ProcessDefinitionEntity();
bpmnParse.setCurrentProcessDefinition(currentProcessDefinition);
/*
* Mapping object model - bpmn xml: processDefinition.id -> generated by
* activiti engine processDefinition.key -> bpmn id (required)
* processDefinition.name -> bpmn name (optional)
*/
currentProcessDefinition.setKey(process.getId());
currentProcessDefinition.setName(process.getName());
currentProcessDefinition.setCategory(bpmnParse.getBpmnModel().getTargetNamespace());
currentProcessDefinition.setDescription(process.getDocumentation());
currentProcessDefinition.setProperty(PROPERTYNAME_DOCUMENTATION, process.getDocumentation()); // Kept for backwards compatibility. See ACT-1020
currentProcessDefinition.setTaskDefinitions(new HashMap<String, TaskDefinition>());
currentProcessDefinition.setDeploymentId(bpmnParse.getDeployment().getId());
createExecutionListenersOnScope(bpmnParse, process.getExecutionListeners(), currentProcessDefinition);
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
for (String candidateUser : process.getCandidateStarterUsers()) {
currentProcessDefinition.addCandidateStarterUserIdExpression(expressionManager.createExpression(candidateUser));
}
for (String candidateGroup : process.getCandidateStarterGroups()) {
currentProcessDefinition.addCandidateStarterGroupIdExpression(expressionManager.createExpression(candidateGroup));
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing process {}", currentProcessDefinition.getKey());
}
bpmnParse.setCurrentScope(currentProcessDefinition);
bpmnParse.processFlowElements(process.getFlowElements());
bpmnParse.processArtifacts(process.getArtifacts(), currentProcessDefinition);
bpmnParse.removeCurrentScope();
if (process.getIoSpecification() != null) {
IOSpecification ioSpecification = bpmnParse.createIOSpecification(process.getIoSpecification());
currentProcessDefinition.setIoSpecification(ioSpecification);
}
return currentProcessDefinition;
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class ReceiveTaskParseHandler extends AbstractActivityBpmnParseHandler<ReceiveTask> {
public Class< ? extends BaseElement> getHandledType() {
return ReceiveTask.class;
}
protected void executeParse(BpmnParse bpmnParse, ReceiveTask receiveTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, receiveTask, BpmnXMLConstants.ELEMENT_TASK_RECEIVE);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createReceiveTaskActivityBehavior(receiveTask));
activity.setAsync(receiveTask.isAsynchronous());
activity.setExclusive(!receiveTask.isNotExclusive());
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class ScriptTaskParseHandler extends AbstractActivityBpmnParseHandler<ScriptTask> {
public Class< ? extends BaseElement> getHandledType() {
return ScriptTask.class;
}
protected void executeParse(BpmnParse bpmnParse, ScriptTask scriptTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, scriptTask, BpmnXMLConstants.ELEMENT_TASK_SCRIPT);
activity.setAsync(scriptTask.isAsynchronous());
activity.setExclusive(!scriptTask.isNotExclusive());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createScriptTaskActivityBehavior(scriptTask));
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.DataAssociation;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.SendTask;
import org.activiti.engine.impl.bpmn.behavior.WebServiceActivityBehavior;
import org.activiti.engine.impl.bpmn.data.AbstractDataAssociation;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.webservice.Operation;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class SendTaskParseHandler extends AbstractExternalInvocationBpmnParseHandler<SendTask> {
public Class< ? extends BaseElement> getHandledType() {
return SendTask.class;
}
protected void executeParse(BpmnParse bpmnParse, SendTask sendTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, sendTask, BpmnXMLConstants.ELEMENT_TASK_SEND);
activity.setAsync(sendTask.isAsynchronous());
activity.setExclusive(!sendTask.isNotExclusive());
// for e-mail
if (StringUtils.isNotEmpty(sendTask.getType())) {
if (sendTask.getType().equalsIgnoreCase("mail")) {
validateFieldDeclarationsForEmail(bpmnParse, sendTask, sendTask.getFieldExtensions());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createMailActivityBehavior(sendTask));
} else if (sendTask.getType().equalsIgnoreCase("mule")) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createMuleActivityBehavior(sendTask, bpmnParse.getBpmnModel()));
} else {
bpmnParse.getBpmnModel().addProblem("Invalid usage of type attribute: '" + sendTask.getType() + "'.", sendTask);
}
// for web service
} else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(sendTask.getImplementationType()) &&
StringUtils.isNotEmpty(sendTask.getOperationRef())) {
if (!bpmnParse.getOperations().containsKey(sendTask.getOperationRef())) {
bpmnParse.getBpmnModel().addProblem(sendTask.getOperationRef() + " does not exist", sendTask);
} else {
WebServiceActivityBehavior webServiceActivityBehavior = bpmnParse.getActivityBehaviorFactory().createWebServiceActivityBehavior(sendTask);
Operation operation = bpmnParse.getOperations().get(sendTask.getOperationRef());
webServiceActivityBehavior.setOperation(operation);
if (sendTask.getIoSpecification() != null) {
IOSpecification ioSpecification = bpmnParse.createIOSpecification(sendTask.getIoSpecification());
webServiceActivityBehavior.setIoSpecification(ioSpecification);
}
for (DataAssociation dataAssociationElement : sendTask.getDataInputAssociations()) {
AbstractDataAssociation dataAssociation = bpmnParse.createDataInputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataInputAssociation(dataAssociation);
}
for (DataAssociation dataAssociationElement : sendTask.getDataOutputAssociations()) {
AbstractDataAssociation dataAssociation = bpmnParse.createDataOutputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataOutputAssociation(dataAssociation);
}
activity.setActivityBehavior(webServiceActivityBehavior);
}
} else {
bpmnParse.getBpmnModel().addProblem("One of the attributes 'type' or 'operation' is mandatory on sendTask.", sendTask);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.Condition;
import org.activiti.engine.impl.bpmn.behavior.EventBasedGatewayActivityBehavior;
import org.activiti.engine.impl.bpmn.behavior.IntermediateCatchEventActivityBehavior;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.UelExpressionCondition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class SequenceFlowParseHandler extends AbstractBpmnParseHandler<SequenceFlow> {
public static final String PROPERTYNAME_CONDITION = "condition";
public static final String PROPERTYNAME_CONDITION_TEXT = "conditionText";
public Class< ? extends BaseElement> getHandledType() {
return SequenceFlow.class;
}
protected void executeParse(BpmnParse bpmnParse, SequenceFlow sequenceFlow) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
ScopeImpl scope = bpmnParse.getCurrentScope();
// Implicit check: sequence flow cannot cross (sub) process boundaries: we
// don't do a processDefinition.findActivity here
ActivityImpl sourceActivity = scope.findActivity(sequenceFlow.getSourceRef());
ActivityImpl destinationActivity = scope.findActivity(sequenceFlow.getTargetRef());
if (sourceActivity == null) {
bpmnModel.addProblem("Invalid source '" + sequenceFlow.getSourceRef() + "' of sequence flow '" + sequenceFlow.getId() + "'", sequenceFlow);
} else if (destinationActivity == null) {
throw new ActivitiException("Invalid destination '" + sequenceFlow.getTargetRef() + "' of sequence flow '" + sequenceFlow.getId() + "'");
} else if (!(sourceActivity.getActivityBehavior() instanceof EventBasedGatewayActivityBehavior)
&& destinationActivity.getActivityBehavior() instanceof IntermediateCatchEventActivityBehavior && (destinationActivity.getParentActivity() != null)
&& (destinationActivity.getParentActivity().getActivityBehavior() instanceof EventBasedGatewayActivityBehavior)) {
bpmnModel.addProblem("Invalid incoming sequenceflow " + sequenceFlow.getId() + " for intermediateCatchEvent with id '" + destinationActivity.getId()
+ "' connected to an event-based gateway.", sequenceFlow);
} else {
TransitionImpl transition = sourceActivity.createOutgoingTransition(sequenceFlow.getId());
bpmnParse.getSequenceFlows().put(sequenceFlow.getId(), transition);
transition.setProperty("name", sequenceFlow.getName());
transition.setProperty("documentation", sequenceFlow.getDocumentation());
transition.setDestination(destinationActivity);
if (StringUtils.isNotEmpty(sequenceFlow.getConditionExpression())) {
Condition expressionCondition = new UelExpressionCondition(bpmnParse.getExpressionManager().createExpression(sequenceFlow.getConditionExpression()));
transition.setProperty(PROPERTYNAME_CONDITION_TEXT, sequenceFlow.getConditionExpression());
transition.setProperty(PROPERTYNAME_CONDITION, expressionCondition);
}
createExecutionListenersOnTransition(bpmnParse, sequenceFlow.getExecutionListeners(), transition);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.DataAssociation;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.engine.impl.bpmn.behavior.WebServiceActivityBehavior;
import org.activiti.engine.impl.bpmn.data.AbstractDataAssociation;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class ServiceTaskParseHandler extends AbstractExternalInvocationBpmnParseHandler<ServiceTask> {
public Class< ? extends BaseElement> getHandledType() {
return ServiceTask.class;
}
protected void executeParse(BpmnParse bpmnParse, ServiceTask serviceTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, serviceTask, BpmnXMLConstants.ELEMENT_TASK_SERVICE);
activity.setAsync(serviceTask.isAsynchronous());
activity.setExclusive(!serviceTask.isNotExclusive());
// Email, Mule and Shell service tasks
if (StringUtils.isNotEmpty(serviceTask.getType())) {
if (serviceTask.getType().equalsIgnoreCase("mail")) {
validateFieldDeclarationsForEmail(bpmnParse, serviceTask, serviceTask.getFieldExtensions());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createMailActivityBehavior(serviceTask));
} else if (serviceTask.getType().equalsIgnoreCase("mule")) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createMuleActivityBehavior(serviceTask, bpmnParse.getBpmnModel()));
} else if (serviceTask.getType().equalsIgnoreCase("shell")) {
validateFieldDeclarationsForShell(bpmnParse, serviceTask, serviceTask.getFieldExtensions());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createShellActivityBehavior(serviceTask));
} else {
bpmnParse.getBpmnModel().addProblem("Invalid usage of type attribute: '" + serviceTask.getType() + "'.", serviceTask);
}
// activiti:class
} else if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createClassDelegateServiceTask(serviceTask));
// activiti:delegateExpression
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskDelegateExpressionActivityBehavior(serviceTask));
// activiti:expression
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(serviceTask.getImplementationType())) {
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createServiceTaskExpressionActivityBehavior(serviceTask));
// Webservice
} else if (ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE.equalsIgnoreCase(serviceTask.getImplementationType()) &&
StringUtils.isNotEmpty(serviceTask.getOperationRef())) {
if (!bpmnParse.getOperations().containsKey(serviceTask.getOperationRef())) {
bpmnParse.getBpmnModel().addProblem(serviceTask.getOperationRef() + " does not exist", serviceTask);
} else {
WebServiceActivityBehavior webServiceActivityBehavior = bpmnParse.getActivityBehaviorFactory().createWebServiceActivityBehavior(serviceTask);
webServiceActivityBehavior.setOperation(bpmnParse.getOperations().get(serviceTask.getOperationRef()));
if (serviceTask.getIoSpecification() != null) {
IOSpecification ioSpecification = bpmnParse.createIOSpecification(serviceTask.getIoSpecification());
webServiceActivityBehavior.setIoSpecification(ioSpecification);
}
for (DataAssociation dataAssociationElement : serviceTask.getDataInputAssociations()) {
AbstractDataAssociation dataAssociation = bpmnParse.createDataInputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataInputAssociation(dataAssociation);
}
for (DataAssociation dataAssociationElement : serviceTask.getDataOutputAssociations()) {
AbstractDataAssociation dataAssociation = bpmnParse.createDataOutputAssociation(dataAssociationElement);
webServiceActivityBehavior.addDataOutputAssociation(dataAssociation);
}
activity.setActivityBehavior(webServiceActivityBehavior);
}
} else {
bpmnParse.getBpmnModel().addProblem("One of the attributes 'class', 'delegateExpression', 'type', 'operation', or 'expression' is mandatory on serviceTask.", serviceTask);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.EventSubscriptionDeclaration;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class SignalEventDefinitionParseHandler extends AbstractBpmnParseHandler<SignalEventDefinition> {
public Class< ? extends BaseElement> getHandledType() {
return SignalEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, SignalEventDefinition signalDefinition) {
if (bpmnParse.getBpmnModel().containsSignalId(signalDefinition.getSignalRef())) {
String signalName = bpmnParse.getBpmnModel().getSignal(signalDefinition.getSignalRef()).getName();
if (StringUtils.isEmpty(signalName)) {
bpmnParse.getBpmnModel().addProblem("signalName is required for a signal event", signalDefinition);
}
signalDefinition.setSignalRef(signalName);
}
ActivityImpl activity = bpmnParse.getCurrentActivity();
if (bpmnParse.getCurrentFlowElement() instanceof StartEvent) {
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(signalDefinition.getSignalRef(), "signal");
eventSubscriptionDeclaration.setActivityId(activity.getId());
eventSubscriptionDeclaration.setStartEvent(false);
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, signalDefinition, bpmnParse.getCurrentScope());
} else if (bpmnParse.getCurrentFlowElement() instanceof IntermediateCatchEvent){
activity.setProperty("type", "intermediateSignalCatch");
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(signalDefinition.getSignalRef(), "signal");
if (getPrecedingEventBasedGateway(bpmnParse, (IntermediateCatchEvent) bpmnParse.getCurrentFlowElement()) != null) {
eventSubscriptionDeclaration.setActivityId(activity.getId());
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, signalDefinition, activity.getParent());
} else {
activity.setScope(true);
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, signalDefinition, activity);
}
} else if (bpmnParse.getCurrentFlowElement() instanceof ThrowEvent) {
activity.setProperty("type", "intermediateSignalThrow");
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(signalDefinition.getSignalRef(), "signal");
eventSubscriptionDeclaration.setAsync(signalDefinition.isAsync());
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createIntermediateThrowSignalEventActivityBehavior((ThrowEvent) bpmnParse.getCurrentFlowElement(), eventSubscriptionDeclaration));
} else if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
BoundaryEvent boundaryEvent = (BoundaryEvent) bpmnParse.getCurrentFlowElement();
boolean interrupting = boundaryEvent.isCancelActivity();
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createBoundaryEventActivityBehavior(boundaryEvent, interrupting, activity));
activity.setProperty("type", "boundarySignal");
EventSubscriptionDeclaration eventSubscriptionDeclaration = new EventSubscriptionDeclaration(signalDefinition.getSignalRef(), "signal");
eventSubscriptionDeclaration.setActivityId(activity.getId());
addEventSubscriptionDeclaration(bpmnParse, eventSubscriptionDeclaration, signalDefinition, activity.getParent());
if (activity.getParent() instanceof ActivityImpl) {
((ActivityImpl) activity.getParent()).setScope(true);
}
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.EventDefinition;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.engine.impl.bpmn.behavior.EventSubProcessStartEventActivityBehavior;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.form.DefaultStartFormHandler;
import org.activiti.engine.impl.form.StartFormHandler;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class StartEventParseHandler extends AbstractActivityBpmnParseHandler<StartEvent> {
public static final String PROPERTYNAME_INITIATOR_VARIABLE_NAME = "initiatorVariableName";
public static final String PROPERTYNAME_INITIAL = "initial";
@Override
public Class< ? extends BaseElement> getHandledType() {
return StartEvent.class;
}
@Override
protected void executeParse(BpmnParse bpmnParse, StartEvent startEvent) {
ActivityImpl startEventActivity = createActivityOnCurrentScope(bpmnParse, startEvent, BpmnXMLConstants.ELEMENT_EVENT_START);
ScopeImpl scope = bpmnParse.getCurrentScope();
if (scope instanceof ProcessDefinitionEntity) {
createProcessDefinitionStartEvent(bpmnParse, startEventActivity, startEvent, (ProcessDefinitionEntity) scope);
selectInitial(bpmnParse, startEventActivity, startEvent, (ProcessDefinitionEntity) scope);
createStartFormHandlers(bpmnParse, startEvent, (ProcessDefinitionEntity) scope);
} else {
createScopeStartEvent(bpmnParse, startEventActivity, startEvent);
}
}
protected void selectInitial(BpmnParse bpmnParse, ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (processDefinition.getInitial() == null) {
processDefinition.setInitial(startEventActivity);
} else {
// validate that there is s single none start event / timer start event:
if (startEventActivity.getProperty("type").equals("messageStartEvent") == false) {
String currentInitialType = (String) processDefinition.getInitial().getProperty("type");
if (currentInitialType.equals("messageStartEvent")) {
processDefinition.setInitial(startEventActivity);
} else {
bpmnParse.getBpmnModel().addProblem("multiple none start events or timer start events not supported on process definition.", startEvent);
}
}
}
}
protected void createStartFormHandlers(BpmnParse bpmnParse, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (processDefinition.getInitial() != null) {
if (startEvent.getId().equals(processDefinition.getInitial().getId())) {
StartFormHandler startFormHandler = new DefaultStartFormHandler();
startFormHandler.parseConfiguration(startEvent.getFormProperties(), startEvent.getFormKey(), bpmnParse.getDeployment(), processDefinition);
processDefinition.setStartFormHandler(startFormHandler);
}
}
}
protected void createProcessDefinitionStartEvent(BpmnParse bpmnParse, ActivityImpl startEventActivity, StartEvent startEvent, ProcessDefinitionEntity processDefinition) {
if (StringUtils.isNotEmpty(startEvent.getInitiator())) {
processDefinition.setProperty(PROPERTYNAME_INITIATOR_VARIABLE_NAME, startEvent.getInitiator());
}
// all start events share the same behavior:
startEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createNoneStartEventActivityBehavior(startEvent));
if (startEvent.getEventDefinitions().size() > 0) {
EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
if (eventDefinition instanceof TimerEventDefinition || eventDefinition instanceof MessageEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else {
bpmnParse.getBpmnModel().addProblem("Unsupported event definition on start event", eventDefinition);
}
}
}
protected void createScopeStartEvent(BpmnParse bpmnParse, ActivityImpl startEventActivity, StartEvent startEvent) {
ScopeImpl scope = bpmnParse.getCurrentScope();
Object triggeredByEvent = scope.getProperty("triggeredByEvent");
boolean isTriggeredByEvent = triggeredByEvent != null && ((Boolean) triggeredByEvent == true);
if (isTriggeredByEvent) { // event subprocess
// all start events of an event subprocess share common behavior
EventSubProcessStartEventActivityBehavior activityBehavior =
bpmnParse.getActivityBehaviorFactory().createEventSubProcessStartEventActivityBehavior(startEvent, startEventActivity.getId());
startEventActivity.setActivityBehavior(activityBehavior);
if (startEvent.getEventDefinitions().size() > 0) {
EventDefinition eventDefinition = startEvent.getEventDefinitions().get(0);
if (eventDefinition instanceof org.activiti.bpmn.model.ErrorEventDefinition
|| eventDefinition instanceof MessageEventDefinition
|| eventDefinition instanceof SignalEventDefinition) {
bpmnParse.getBpmnParserHandlers().parse(bpmnParse, eventDefinition);
} else {
bpmnParse.getBpmnModel().addProblem("start event of event subprocess must be of type 'error', 'message' or 'signal' ", startEvent);
}
}
} else { // "regular" subprocess
if(startEvent.getEventDefinitions().size() > 0) {
bpmnParse.getBpmnModel().addProblem("event definitions only allowed on start event if subprocess is an event subprocess", startEvent);
}
if (scope.getProperty(PROPERTYNAME_INITIAL) == null) {
scope.setProperty(PROPERTYNAME_INITIAL, startEventActivity);
startEventActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createNoneStartEventActivityBehavior(startEvent));
} else {
bpmnParse.getBpmnModel().addProblem("multiple start events not supported for subprocess", bpmnParse.getCurrentSubProcess());
}
}
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.HashSet;
import java.util.Set;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.EventSubProcess;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class SubProcessParseHandler extends AbstractActivityBpmnParseHandler<SubProcess> {
protected static Set<Class<? extends BaseElement>> supportedTypes = new HashSet<Class<? extends BaseElement>>();
static {
supportedTypes.add(SubProcess.class);
supportedTypes.add(EventSubProcess.class);
}
public Set<Class< ? extends BaseElement>> getHandledTypes() {
return supportedTypes;
}
protected void executeParse(BpmnParse bpmnParse, SubProcess subProcess) {
ActivityImpl activity = createActivityOnScope(bpmnParse, subProcess, BpmnXMLConstants.ELEMENT_SUBPROCESS, bpmnParse.getCurrentScope());
activity.setAsync(subProcess.isAsynchronous());
activity.setExclusive(!subProcess.isNotExclusive());
boolean triggeredByEvent = false;
if (subProcess instanceof EventSubProcess) {
triggeredByEvent = true;
}
activity.setProperty("triggeredByEvent", triggeredByEvent);
// event subprocesses are not scopes
activity.setScope(!triggeredByEvent);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createSubprocActivityBehavior(subProcess));
bpmnParse.setCurrentScope(activity);
bpmnParse.setCurrentSubProcess(subProcess);
bpmnParse.processFlowElements(subProcess.getFlowElements());
bpmnParse.processArtifacts(subProcess.getArtifacts(), activity);
bpmnParse.removeCurrentScope();
bpmnParse.removeCurrentSubProcess();
if (subProcess.getIoSpecification() != null) {
IOSpecification ioSpecification = bpmnParse.createIOSpecification(subProcess.getIoSpecification());
activity.setIoSpecification(ioSpecification);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.Task;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class TaskParseHandler extends AbstractActivityBpmnParseHandler<Task> {
public Class< ? extends BaseElement> getHandledType() {
return Task.class;
}
protected void executeParse(BpmnParse bpmnParse, Task task) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, task, BpmnXMLConstants.ELEMENT_TASK);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createTaskActivityBehavior(task));
activity.setAsync(task.isAsynchronous());
activity.setExclusive(!task.isNotExclusive());
}
}
/* 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.impl.bpmn.parser.handler;
import java.util.ArrayList;
import java.util.List;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.jobexecutor.TimerCatchIntermediateEventJobHandler;
import org.activiti.engine.impl.jobexecutor.TimerDeclarationImpl;
import org.activiti.engine.impl.jobexecutor.TimerDeclarationType;
import org.activiti.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler;
import org.activiti.engine.impl.jobexecutor.TimerStartEventJobHandler;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class TimerEventDefinitionParseHandler extends AbstractBpmnParseHandler<TimerEventDefinition> {
public static final String PROPERTYNAME_START_TIMER = "timerStart";
public Class< ? extends BaseElement> getHandledType() {
return TimerEventDefinition.class;
}
protected void executeParse(BpmnParse bpmnParse, TimerEventDefinition timerEventDefinition) {
ActivityImpl timerActivity = bpmnParse.getCurrentActivity();
if (bpmnParse.getCurrentFlowElement() instanceof StartEvent) {
ProcessDefinitionEntity processDefinition = bpmnParse.getCurrentProcessDefinition();
timerActivity.setProperty("type", "startTimerEvent");
TimerDeclarationImpl timerDeclaration = createTimer(bpmnParse, timerEventDefinition, timerActivity, TimerStartEventJobHandler.TYPE);
timerDeclaration.setJobHandlerConfiguration(processDefinition.getKey());
List<TimerDeclarationImpl> timerDeclarations = (List<TimerDeclarationImpl>) processDefinition.getProperty(PROPERTYNAME_START_TIMER);
if (timerDeclarations == null) {
timerDeclarations = new ArrayList<TimerDeclarationImpl>();
processDefinition.setProperty(PROPERTYNAME_START_TIMER, timerDeclarations);
}
timerDeclarations.add(timerDeclaration);
} else if (bpmnParse.getCurrentFlowElement() instanceof IntermediateCatchEvent) {
timerActivity.setProperty("type", "intermediateTimer");
TimerDeclarationImpl timerDeclaration = createTimer(bpmnParse, timerEventDefinition, timerActivity, TimerCatchIntermediateEventJobHandler.TYPE);
if (getPrecedingEventBasedGateway(bpmnParse, (IntermediateCatchEvent) bpmnParse.getCurrentFlowElement()) != null) {
addTimerDeclaration(timerActivity.getParent(), timerDeclaration);
} else {
addTimerDeclaration(timerActivity, timerDeclaration);
timerActivity.setScope(true);
}
} else if (bpmnParse.getCurrentFlowElement() instanceof BoundaryEvent) {
timerActivity.setProperty("type", "boundaryTimer");
TimerDeclarationImpl timerDeclaration = createTimer(bpmnParse, timerEventDefinition, timerActivity, TimerExecuteNestedActivityJobHandler.TYPE);
// ACT-1427
BoundaryEvent boundaryEvent = (BoundaryEvent) bpmnParse.getCurrentFlowElement();
boolean interrupting = boundaryEvent.isCancelActivity();
if (interrupting) {
timerDeclaration.setInterruptingTimer(true);
}
addTimerDeclaration(timerActivity.getParent(), timerDeclaration);
if (timerActivity.getParent() instanceof ActivityImpl) {
((ActivityImpl) timerActivity.getParent()).setScope(true);
}
timerActivity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory()
.createBoundaryEventActivityBehavior((BoundaryEvent) bpmnParse.getCurrentFlowElement(), interrupting, timerActivity));
}
}
protected TimerDeclarationImpl createTimer(BpmnParse bpmnParse, TimerEventDefinition timerEventDefinition, ScopeImpl timerActivity, String jobHandlerType) {
TimerDeclarationType type = null;
Expression expression = null;
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDate())) {
// TimeDate
type = TimerDeclarationType.DATE;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDate());
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeCycle())) {
// TimeCycle
type = TimerDeclarationType.CYCLE;
expression = expressionManager.createExpression(timerEventDefinition.getTimeCycle());
} else if (StringUtils.isNotEmpty(timerEventDefinition.getTimeDuration())) {
// TimeDuration
type = TimerDeclarationType.DURATION;
expression = expressionManager.createExpression(timerEventDefinition.getTimeDuration());
}
// neither date, cycle or duration configured!
if (expression == null) {
bpmnParse.getBpmnModel().addProblem("Timer needs configuration (either timeDate, timeCycle or timeDuration is needed).", timerEventDefinition);
}
// Parse the timer declaration
// TODO move the timer declaration into the bpmn activity or next to the
// TimerSession
TimerDeclarationImpl timerDeclaration = new TimerDeclarationImpl(expression, type, jobHandlerType);
timerDeclaration.setJobHandlerConfiguration(timerActivity.getId());
timerDeclaration.setExclusive(true);
return timerDeclaration;
}
@SuppressWarnings("unchecked")
protected void addTimerDeclaration(ScopeImpl scope, TimerDeclarationImpl timerDeclaration) {
List<TimerDeclarationImpl> timerDeclarations = (List<TimerDeclarationImpl>) scope.getProperty(PROPERTYNAME_TIMER_DECLARATION);
if (timerDeclarations == null) {
timerDeclarations = new ArrayList<TimerDeclarationImpl>();
scope.setProperty(PROPERTYNAME_TIMER_DECLARATION, timerDeclarations);
}
timerDeclarations.add(timerDeclaration);
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.Transaction;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* @author Joram Barrez
*/
public class TransactionParseHandler extends AbstractActivityBpmnParseHandler<Transaction> {
public Class< ? extends BaseElement> getHandledType() {
return Transaction.class;
}
protected void executeParse(BpmnParse bpmnParse, Transaction transaction) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, transaction, BpmnXMLConstants.ELEMENT_TRANSACTION);
activity.setAsync(transaction.isAsynchronous());
activity.setExclusive(!transaction.isNotExclusive());
activity.setScope(true);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createTransactionActivityBehavior(transaction));
bpmnParse.setCurrentScope(activity);
bpmnParse.processFlowElements(transaction.getFlowElements());
bpmnParse.processArtifacts(transaction.getArtifacts(), activity);
bpmnParse.removeCurrentScope();
if (transaction.getIoSpecification() != null) {
IOSpecification ioSpecification = bpmnParse.createIOSpecification(transaction.getIoSpecification());
activity.setIoSpecification(ioSpecification);
}
}
}
/* 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.impl.bpmn.parser.handler;
import org.activiti.bpmn.constants.BpmnXMLConstants;
import org.activiti.bpmn.model.ActivitiListener;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.ImplementationType;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.form.DefaultTaskFormHandler;
import org.activiti.engine.impl.form.TaskFormHandler;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.apache.commons.lang.StringUtils;
/**
* @author Joram Barrez
*/
public class UserTaskParseHandler extends AbstractActivityBpmnParseHandler<UserTask> {
public static final String PROPERTY_TASK_DEFINITION = "taskDefinition";
public Class< ? extends BaseElement> getHandledType() {
return UserTask.class;
}
protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, userTask, BpmnXMLConstants.ELEMENT_TASK_USER);
activity.setAsync(userTask.isAsynchronous());
activity.setExclusive(!userTask.isNotExclusive());
TaskDefinition taskDefinition = parseTaskDefinition(bpmnParse, userTask, userTask.getId(), (ProcessDefinitionEntity) bpmnParse.getCurrentScope().getProcessDefinition());
activity.setProperty(PROPERTY_TASK_DEFINITION, taskDefinition);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask, taskDefinition));
}
public TaskDefinition parseTaskDefinition(BpmnParse bpmnParse, UserTask userTask, String taskDefinitionKey, ProcessDefinitionEntity processDefinition) {
TaskFormHandler taskFormHandler = new DefaultTaskFormHandler();
taskFormHandler.parseConfiguration(userTask.getFormProperties(), userTask.getFormKey(), bpmnParse.getDeployment(), processDefinition);
TaskDefinition taskDefinition = new TaskDefinition(taskFormHandler);
taskDefinition.setKey(taskDefinitionKey);
processDefinition.getTaskDefinitions().put(taskDefinitionKey, taskDefinition);
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
if (StringUtils.isNotEmpty(userTask.getName())) {
taskDefinition.setNameExpression(expressionManager.createExpression(userTask.getName()));
}
if (StringUtils.isNotEmpty(userTask.getDocumentation())) {
taskDefinition.setDescriptionExpression(expressionManager.createExpression(userTask.getDocumentation()));
}
if (StringUtils.isNotEmpty(userTask.getAssignee())) {
taskDefinition.setAssigneeExpression(expressionManager.createExpression(userTask.getAssignee()));
}
for (String candidateUser : userTask.getCandidateUsers()) {
taskDefinition.addCandidateUserIdExpression(expressionManager.createExpression(candidateUser));
}
for (String candidateGroup : userTask.getCandidateGroups()) {
taskDefinition.addCandidateGroupIdExpression(expressionManager.createExpression(candidateGroup));
}
// Activiti custom extension
// Task listeners
for (ActivitiListener taskListener : userTask.getTaskListeners()) {
taskDefinition.addTaskListener(taskListener.getEvent(), createTaskListener(bpmnParse, taskListener, userTask.getId()));
}
// Due date
if (StringUtils.isNotEmpty(userTask.getDueDate())) {
taskDefinition.setDueDateExpression(expressionManager.createExpression(userTask.getDueDate()));
}
// Priority
if (StringUtils.isNotEmpty(userTask.getPriority())) {
taskDefinition.setPriorityExpression(expressionManager.createExpression(userTask.getPriority()));
}
return taskDefinition;
}
protected TaskListener createTaskListener(BpmnParse bpmnParse, ActivitiListener activitiListener, String taskId) {
TaskListener taskListener = null;
if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = bpmnParse.getListenerFactory().createClassDelegateTaskListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = bpmnParse.getListenerFactory().createExpressionTaskListener(activitiListener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(activitiListener.getImplementationType())) {
taskListener = bpmnParse.getListenerFactory().createDelegateExpressionTaskListener(activitiListener);
} else {
bpmnParse.getBpmnModel().addProblem("Element 'class', 'expression' or 'delegateExpression' is mandatory on taskListener for task", activitiListener);
}
return taskListener;
}
}
......@@ -30,7 +30,6 @@ import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.BpmnParseListener;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
......@@ -52,11 +51,40 @@ import org.activiti.engine.impl.ServiceImpl;
import org.activiti.engine.impl.TaskServiceImpl;
import org.activiti.engine.impl.bpmn.data.ItemInstance;
import org.activiti.engine.impl.bpmn.deployer.BpmnDeployer;
import org.activiti.engine.impl.bpmn.parser.BpmnParseHandlers;
import org.activiti.engine.impl.bpmn.parser.BpmnParser;
import org.activiti.engine.impl.bpmn.parser.factory.ActivityBehaviorFactory;
import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory;
import org.activiti.engine.impl.bpmn.parser.factory.DefaultListenerFactory;
import org.activiti.engine.impl.bpmn.parser.factory.ListenerFactory;
import org.activiti.engine.impl.bpmn.parser.handler.BoundaryEventParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.BusinessRuleParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.CallActivityParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.CancelEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.CompensateEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.EndEventParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ErrorEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.EventBasedGatewayParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ExclusiveGatewayParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.InclusiveGatewayParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.IntermediateCatchEventParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.IntermediateThrowEventParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ManualTaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.MessageEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ParallelGatewayParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ReceiveTaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ScriptTaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.SendTaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.SequenceFlowParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.ServiceTaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.SignalEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.StartEventParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.SubProcessParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.TaskParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.TimerEventDefinitionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.TransactionParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.UserTaskParseHandler;
import org.activiti.engine.impl.bpmn.webservice.MessageInstance;
import org.activiti.engine.impl.calendar.BusinessCalendarManager;
import org.activiti.engine.impl.calendar.CycleBusinessCalendar;
......@@ -82,7 +110,10 @@ import org.activiti.engine.impl.form.LongFormType;
import org.activiti.engine.impl.form.StringFormType;
import org.activiti.engine.impl.history.HistoryLevel;
import org.activiti.engine.impl.history.HistoryManager;
import org.activiti.engine.impl.history.handler.HistoryParseListener;
import org.activiti.engine.impl.history.parse.FlowNodeHistoryParseHandler;
import org.activiti.engine.impl.history.parse.ProcessHistoryParseHandler;
import org.activiti.engine.impl.history.parse.StartEventHistoryParseHandler;
import org.activiti.engine.impl.history.parse.UserTaskHistoryParseHandler;
import org.activiti.engine.impl.interceptor.CommandContextFactory;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.interceptor.CommandExecutorImpl;
......@@ -157,6 +188,7 @@ import org.activiti.engine.impl.variable.ShortType;
import org.activiti.engine.impl.variable.StringType;
import org.activiti.engine.impl.variable.VariableType;
import org.activiti.engine.impl.variable.VariableTypes;
import org.activiti.engine.parse.BpmnParseHandler;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
......@@ -253,8 +285,8 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
protected String idGeneratorDataSourceJndiName;
// Bpmn parser
protected List<BpmnParseListener> preParseListeners;
protected List<BpmnParseListener> postParseListeners;
protected List<BpmnParseHandler> preBpmnParseHandlers;
protected List<BpmnParseHandler> postBpmnParseHandlers;
protected ActivityBehaviorFactory activityBehaviorFactory;
protected ListenerFactory listenerFactory;
protected BpmnParseFactory bpmnParseFactory;
......@@ -733,24 +765,72 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
bpmnParser.setActivityBehaviorFactory(activityBehaviorFactory);
bpmnParser.setListenerFactory(listenerFactory);
if(preParseListeners != null) {
bpmnParser.getParseListeners().addAll(preParseListeners);
List<BpmnParseHandler> parseHandlers = new ArrayList<BpmnParseHandler>();
if(getPreBpmnParseHandlers() != null) {
parseHandlers.addAll(getPreBpmnParseHandlers());
}
bpmnParser.getParseListeners().addAll(getDefaultBPMNParseListeners());
if(postParseListeners != null) {
bpmnParser.getParseListeners().addAll(postParseListeners);
parseHandlers.addAll(getDefaultBpmnParseHandlers());
if(getPostBpmnParseHandlers() != null) {
parseHandlers.addAll(getPostBpmnParseHandlers());
}
BpmnParseHandlers bpmnParseHandlers = new BpmnParseHandlers();
bpmnParseHandlers.addHandlers(parseHandlers);
bpmnParser.setBpmnParserHandlers(bpmnParseHandlers);
bpmnDeployer.setBpmnParser(bpmnParser);
defaultDeployers.add(bpmnDeployer);
return defaultDeployers;
}
protected List<BpmnParseListener> getDefaultBPMNParseListeners() {
List<BpmnParseListener> defaultListeners = new ArrayList<BpmnParseListener>();
defaultListeners.add(new HistoryParseListener());
return defaultListeners;
protected List<BpmnParseHandler> getDefaultBpmnParseHandlers() {
// Alpabetic list of default parse handler classes
List<BpmnParseHandler> bpmnParserHandlers = new ArrayList<BpmnParseHandler>();
bpmnParserHandlers.add(new BoundaryEventParseHandler());
bpmnParserHandlers.add(new BusinessRuleParseHandler());
bpmnParserHandlers.add(new CallActivityParseHandler());
bpmnParserHandlers.add(new CancelEventDefinitionParseHandler());
bpmnParserHandlers.add(new CompensateEventDefinitionParseHandler());
bpmnParserHandlers.add(new EndEventParseHandler());
bpmnParserHandlers.add(new ErrorEventDefinitionParseHandler());
bpmnParserHandlers.add(new EventBasedGatewayParseHandler());
bpmnParserHandlers.add(new ExclusiveGatewayParseHandler());
bpmnParserHandlers.add(new InclusiveGatewayParseHandler());
bpmnParserHandlers.add(new IntermediateCatchEventParseHandler());
bpmnParserHandlers.add(new IntermediateThrowEventParseHandler());
bpmnParserHandlers.add(new ManualTaskParseHandler());
bpmnParserHandlers.add(new MessageEventDefinitionParseHandler());
bpmnParserHandlers.add(new ParallelGatewayParseHandler());
bpmnParserHandlers.add(new ProcessParseHandler());
bpmnParserHandlers.add(new ReceiveTaskParseHandler());
bpmnParserHandlers.add(new ScriptTaskParseHandler());
bpmnParserHandlers.add(new SendTaskParseHandler());
bpmnParserHandlers.add(new SequenceFlowParseHandler());
bpmnParserHandlers.add(new ServiceTaskParseHandler());
bpmnParserHandlers.add(new SignalEventDefinitionParseHandler());
bpmnParserHandlers.add(new StartEventParseHandler());
bpmnParserHandlers.add(new SubProcessParseHandler());
bpmnParserHandlers.add(new TaskParseHandler());
bpmnParserHandlers.add(new TimerEventDefinitionParseHandler());
bpmnParserHandlers.add(new TransactionParseHandler());
bpmnParserHandlers.add(new UserTaskParseHandler());
// History
for (BpmnParseHandler handler : getDefaultHistoryParseHandlers()) {
bpmnParserHandlers.add(handler);
}
return bpmnParserHandlers;
}
protected List<BpmnParseHandler> getDefaultHistoryParseHandlers() {
List<BpmnParseHandler> parseHandlers = new ArrayList<BpmnParseHandler>();
parseHandlers.add(new FlowNodeHistoryParseHandler());
parseHandlers.add(new ProcessHistoryParseHandler());
parseHandlers.add(new StartEventHistoryParseHandler());
parseHandlers.add(new UserTaskHistoryParseHandler());
return parseHandlers;
}
// job executor /////////////////////////////////////////////////////////////
......@@ -1393,39 +1473,23 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig
this.customPostVariableTypes = customPostVariableTypes;
return this;
}
public List<BpmnParseListener> getCustomPreBPMNParseListeners() {
return preParseListeners;
}
public void setCustomPreBPMNParseListeners(List<BpmnParseListener> preParseListeners) {
this.preParseListeners = preParseListeners;
}
public List<BpmnParseListener> getCustomPostBPMNParseListeners() {
return postParseListeners;
}
public void setCustomPostBPMNParseListeners(List<BpmnParseListener> postParseListeners) {
this.postParseListeners = postParseListeners;
public List<BpmnParseHandler> getPreBpmnParseHandlers() {
return preBpmnParseHandlers;
}
public List<BpmnParseListener> getPreParseListeners() {
return preParseListeners;
public void setPreBpmnParseHandlers(List<BpmnParseHandler> preBpmnParseHandlers) {
this.preBpmnParseHandlers = preBpmnParseHandlers;
}
public void setPreParseListeners(List<BpmnParseListener> preParseListeners) {
this.preParseListeners = preParseListeners;
}
public List<BpmnParseListener> getPostParseListeners() {
return postParseListeners;
public List<BpmnParseHandler> getPostBpmnParseHandlers() {
return postBpmnParseHandlers;
}
public void setPostParseListeners(List<BpmnParseListener> postParseListeners) {
this.postParseListeners = postParseListeners;
public void setPostBpmnParseHandlers(List<BpmnParseHandler> postBpmnParseHandlers) {
this.postBpmnParseHandlers = postBpmnParseHandlers;
}
public ActivityBehaviorFactory getActivityBehaviorFactory() {
return activityBehaviorFactory;
}
......
/* 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.impl.history.handler;
import java.util.List;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ErrorEventDefinition;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.MessageEventDefinition;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SignalEventDefinition;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.TimerEventDefinition;
import org.activiti.bpmn.model.Transaction;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.BpmnParseListener;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.impl.util.xml.Element;
import org.activiti.engine.impl.variable.VariableDeclaration;
/**
* Implements writing the history, but not all logic is contained here, see {@link ProcessDefinitionEntity} as well!
*
* @author Tom Baeyens
* @author Joram Barrez
* @author Falko Menge
* @author Bernd Ruecker (camunda)
* @author Christian Lipphardt (camunda)
*/
public class HistoryParseListener implements BpmnParseListener {
protected static final StartEventEndHandler START_EVENT_END_HANDLER = new StartEventEndHandler();
protected static final ActivityInstanceEndHandler ACTIVITI_INSTANCE_END_LISTENER = new ActivityInstanceEndHandler();
protected static final ActivityInstanceStartHandler ACTIVITY_INSTANCE_START_LISTENER = new ActivityInstanceStartHandler();
protected static final UserTaskAssignmentHandler USER_TASK_ASSIGNMENT_HANDLER = new UserTaskAssignmentHandler();
protected static final ProcessInstanceEndHandler PROCESS_INSTANCE_END_HANDLER = new ProcessInstanceEndHandler();
protected static final UserTaskIdHandler USER_TASK_ID_HANDLER = new UserTaskIdHandler();
public void parseProcess(Process processElement, ProcessDefinitionEntity processDefinition) {
processDefinition.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, PROCESS_INSTANCE_END_HANDLER);
}
public void parseExclusiveGateway(ExclusiveGateway exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseInclusiveGateway(InclusiveGateway inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseCallActivity(CallActivity callActivityElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseManualTask(ManualTask manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseReceiveTask(ReceiveTask receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseScriptTask(ScriptTask scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseTask(Task taskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseUserTask(UserTask userTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activity.getActivityBehavior()).getTaskDefinition();
taskDefinition.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, USER_TASK_ASSIGNMENT_HANDLER);
taskDefinition.addTaskListener(TaskListener.EVENTNAME_CREATE, USER_TASK_ID_HANDLER);
}
public void parseServiceTask(ServiceTask serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseBusinessRuleTask(BusinessRuleTask businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseSubProcess(SubProcess subProcessElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseStartEvent(StartEvent startEventElement, ScopeImpl scope, ActivityImpl activity) {
activity.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, START_EVENT_END_HANDLER);
}
public void parseSendTask(SendTask sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseEndEvent(EndEvent endEventElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseParallelGateway(ParallelGateway parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseBoundaryTimerEventDefinition(TimerEventDefinition timerEventDefinition, boolean interrupting, ActivityImpl timerActivity) {
}
public void parseBoundaryErrorEventDefinition(ErrorEventDefinition errorEventDefinition, boolean interrupting, ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
}
public void parseIntermediateTimerEventDefinition(TimerEventDefinition timerEventDefinition, ActivityImpl timerActivity) {
}
public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
}
public void parseSequenceFlow(SequenceFlow sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
}
public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
}
public void parseBoundarySignalEventDefinition(SignalEventDefinition signalEventDefinition, boolean interrupting, ActivityImpl signalActivity) {
}
public void parseEventBasedGateway(EventGateway eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
// TODO: Shall we add audit logging here as well?
}
public void parseMultiInstanceLoopCharacteristics(Activity activityElement,
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
// Remove any history parse listeners already attached: the Multi instance behavior will
// call them for every instance that will be created
}
// helper methods ///////////////////////////////////////////////////////////
protected void addActivityHandlers(ActivityImpl activity) {
activity.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_START, ACTIVITY_INSTANCE_START_LISTENER, 0);
activity.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, ACTIVITI_INSTANCE_END_LISTENER);
}
public void parseIntermediateSignalCatchEventDefinition(SignalEventDefinition signalEventDefinition, ActivityImpl signalActivity) {
}
public void parseTransaction(Transaction transaction, ScopeImpl scope, ActivityImpl activity) {
}
public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
}
public void parseIntermediateThrowEvent(ThrowEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseIntermediateCatchEvent(IntermediateCatchEvent intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
addActivityHandlers(activity);
}
public void parseBoundaryEvent(BoundaryEvent boundaryEventElement, ScopeImpl scopeElement, ActivityImpl activity) {
// TODO: Add to audit logging? Discuss
}
public void parseIntermediateMessageCatchEventDefinition(MessageEventDefinition messageEventDefinition, ActivityImpl nestedActivity) {
}
public void parseBoundaryMessageEventDefinition(MessageEventDefinition element, boolean interrupting, ActivityImpl messageActivity) {
}
}
/* 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.impl.history.parse;
import java.util.HashSet;
import java.util.Set;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BusinessRuleTask;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.EventGateway;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.InclusiveGateway;
import org.activiti.bpmn.model.IntermediateCatchEvent;
import org.activiti.bpmn.model.ManualTask;
import org.activiti.bpmn.model.ParallelGateway;
import org.activiti.bpmn.model.ReceiveTask;
import org.activiti.bpmn.model.ScriptTask;
import org.activiti.bpmn.model.SendTask;
import org.activiti.bpmn.model.ServiceTask;
import org.activiti.bpmn.model.SubProcess;
import org.activiti.bpmn.model.Task;
import org.activiti.bpmn.model.ThrowEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.history.handler.ActivityInstanceEndHandler;
import org.activiti.engine.impl.history.handler.ActivityInstanceStartHandler;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.parse.BpmnParseHandler;
/**
* @author Joram Barrez
*/
public class FlowNodeHistoryParseHandler implements BpmnParseHandler {
protected static final ActivityInstanceEndHandler ACTIVITI_INSTANCE_END_LISTENER = new ActivityInstanceEndHandler();
protected static final ActivityInstanceStartHandler ACTIVITY_INSTANCE_START_LISTENER = new ActivityInstanceStartHandler();
protected static Set<Class<? extends BaseElement>> supportedElementClasses = new HashSet<Class<? extends BaseElement>>();
static {
supportedElementClasses.add(EndEvent.class);
supportedElementClasses.add(ThrowEvent.class);
supportedElementClasses.add(IntermediateCatchEvent.class);
supportedElementClasses.add(ExclusiveGateway.class);
supportedElementClasses.add(InclusiveGateway.class);
supportedElementClasses.add(ParallelGateway.class);
supportedElementClasses.add(EventGateway.class);
supportedElementClasses.add(Task.class);
supportedElementClasses.add(ManualTask.class);
supportedElementClasses.add(ReceiveTask.class);
supportedElementClasses.add(ScriptTask.class);
supportedElementClasses.add(ServiceTask.class);
supportedElementClasses.add(BusinessRuleTask.class);
supportedElementClasses.add(SendTask.class);
supportedElementClasses.add(UserTask.class);
supportedElementClasses.add(CallActivity.class);
supportedElementClasses.add(SubProcess.class);
}
public Set<Class< ? extends BaseElement>> getHandledTypes() {
return supportedElementClasses;
}
public void parse(BpmnParse bpmnParse, BaseElement element) {
ActivityImpl activity = bpmnParse.getCurrentScope().findActivity(element.getId());
activity.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_START, ACTIVITY_INSTANCE_START_LISTENER, 0);
activity.addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, ACTIVITI_INSTANCE_END_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.impl.history.parse;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler;
import org.activiti.engine.impl.history.handler.ProcessInstanceEndHandler;
/**
* @author Joram Barrez
*/
public class ProcessHistoryParseHandler extends AbstractBpmnParseHandler<Process> {
protected static final ProcessInstanceEndHandler PROCESS_INSTANCE_END_HANDLER = new ProcessInstanceEndHandler();
protected Class< ? extends BaseElement> getHandledType() {
return Process.class;
}
protected void executeParse(BpmnParse bpmnParse, Process element) {
bpmnParse.getCurrentProcessDefinition().addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, PROCESS_INSTANCE_END_HANDLER);
}
}
/* 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.impl.history.parse;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler;
import org.activiti.engine.impl.history.handler.StartEventEndHandler;
/**
* @author Joram Barrez
*/
public class StartEventHistoryParseHandler extends AbstractBpmnParseHandler<StartEvent> {
protected static final StartEventEndHandler START_EVENT_END_HANDLER = new StartEventEndHandler();
protected Class< ? extends BaseElement> getHandledType() {
return StartEvent.class;
}
protected void executeParse(BpmnParse bpmnParse, StartEvent element) {
bpmnParse.getCurrentActivity().addExecutionListener(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END, START_EVENT_END_HANDLER);
}
}
/* 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.impl.history.parse;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler;
import org.activiti.engine.impl.bpmn.parser.handler.UserTaskParseHandler;
import org.activiti.engine.impl.history.handler.UserTaskAssignmentHandler;
import org.activiti.engine.impl.history.handler.UserTaskIdHandler;
import org.activiti.engine.impl.task.TaskDefinition;
/**
* @author Joram Barrez
*/
public class UserTaskHistoryParseHandler extends AbstractBpmnParseHandler<UserTask> {
protected static final UserTaskAssignmentHandler USER_TASK_ASSIGNMENT_HANDLER = new UserTaskAssignmentHandler();
protected static final UserTaskIdHandler USER_TASK_ID_HANDLER = new UserTaskIdHandler();
protected Class< ? extends BaseElement> getHandledType() {
return UserTask.class;
}
protected void executeParse(BpmnParse bpmnParse, UserTask element) {
TaskDefinition taskDefinition = (TaskDefinition) bpmnParse.getCurrentActivity().getProperty(UserTaskParseHandler.PROPERTY_TASK_DEFINITION);
taskDefinition.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, USER_TASK_ASSIGNMENT_HANDLER);
taskDefinition.addTaskListener(TaskListener.EVENTNAME_CREATE, USER_TASK_ID_HANDLER);
}
}
......@@ -47,7 +47,6 @@ import org.activiti.engine.impl.pvm.runtime.InterpretableExecution;
import org.activiti.engine.impl.pvm.runtime.OutgoingExecution;
import org.activiti.engine.impl.pvm.runtime.StartingExecution;
import org.activiti.engine.impl.util.BitMaskUtil;
import org.activiti.engine.impl.variable.VariableDeclaration;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.Job;
import org.activiti.engine.runtime.ProcessInstance;
......@@ -281,13 +280,6 @@ public class ExecutionEntity extends VariableScopeImpl implements ActivityExecut
ScopeImpl scope = getScope();
ensureParentInitialized();
List<VariableDeclaration> variableDeclarations = (List<VariableDeclaration>) scope.getProperty(BpmnParse.PROPERTYNAME_VARIABLE_DECLARATIONS);
if (variableDeclarations!=null) {
for (VariableDeclaration variableDeclaration : variableDeclarations) {
variableDeclaration.initialize(this, parent);
}
}
// initialize the lists of referenced objects (prevents db queries)
variableInstances = new HashMap<String, VariableInstanceEntity>();
eventSubscriptions = new ArrayList<EventSubscriptionEntity>();
......
/* 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.impl.variable;
import java.io.Serializable;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.VariableScope;
/**
* @author Tom Baeyens
*/
public class VariableDeclaration implements Serializable {
private static final long serialVersionUID = 1L;
protected String name;
protected String type;
protected String sourceVariableName;
protected Expression sourceExpression;
protected String destinationVariableName;
protected Expression destinationExpression;
protected String link;
protected Expression linkExpression;
public void initialize(VariableScope innerScopeInstance, VariableScope outerScopeInstance) {
if (sourceVariableName!=null) {
if (outerScopeInstance.hasVariable(sourceVariableName)) {
Object value = outerScopeInstance.getVariable(sourceVariableName);
innerScopeInstance.setVariable(destinationVariableName, value);
} else {
throw new ActivitiException("Couldn't create variable '"
+ destinationVariableName + "', since the source variable '"
+ sourceVariableName + "does not exist");
}
}
if (sourceExpression!=null) {
Object value = sourceExpression.getValue(outerScopeInstance);
innerScopeInstance.setVariable(destinationVariableName, value);
}
if (link!=null) {
if (outerScopeInstance.hasVariable(sourceVariableName)) {
Object value = outerScopeInstance.getVariable(sourceVariableName);
innerScopeInstance.setVariable(destinationVariableName, value);
} else {
throw new ActivitiException("Couldn't create variable '" + destinationVariableName + "', since the source variable '" + sourceVariableName
+ "does not exist");
}
}
if (linkExpression!=null) {
Object value = sourceExpression.getValue(outerScopeInstance);
innerScopeInstance.setVariable(destinationVariableName, value);
}
}
public void destroy(VariableScope innerScopeInstance, VariableScope outerScopeInstance) {
if (destinationVariableName!=null) {
if (innerScopeInstance.hasVariable(sourceVariableName)) {
Object value = innerScopeInstance.getVariable(sourceVariableName);
outerScopeInstance.setVariable(destinationVariableName, value);
} else {
throw new ActivitiException("Couldn't destroy variable " + sourceVariableName + ", since it does not exist");
}
}
if (destinationExpression!=null) {
Object value = destinationExpression.getValue(innerScopeInstance);
outerScopeInstance.setVariable(destinationVariableName, value);
}
if (link!=null) {
if (innerScopeInstance.hasVariable(sourceVariableName)) {
Object value = innerScopeInstance.getVariable(sourceVariableName);
outerScopeInstance.setVariable(destinationVariableName, value);
} else {
throw new ActivitiException("Couldn't destroy variable " + sourceVariableName + ", since it does not exist");
}
}
if (linkExpression!=null) {
Object value = sourceExpression.getValue(innerScopeInstance);
outerScopeInstance.setVariable(destinationVariableName, value);
}
}
public VariableDeclaration(String name, String type) {
this.name = name;
this.type = type;
}
@Override
public String toString() {
return "VariableDeclaration[" + name + ":" + type + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSourceVariableName() {
return sourceVariableName;
}
public void setSourceVariableName(String sourceVariableName) {
this.sourceVariableName = sourceVariableName;
}
public Expression getSourceExpression() {
return sourceExpression;
}
public void setSourceExpression(Expression sourceExpression) {
this.sourceExpression = sourceExpression;
}
public String getDestinationVariableName() {
return destinationVariableName;
}
public void setDestinationVariableName(String destinationVariableName) {
this.destinationVariableName = destinationVariableName;
}
public Expression getDestinationExpression() {
return destinationExpression;
}
public void setDestinationExpression(Expression destinationExpression) {
this.destinationExpression = destinationExpression;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Expression getLinkExpression() {
return linkExpression;
}
public void setLinkExpression(Expression linkExpression) {
this.linkExpression = linkExpression;
}
}
/* 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.parse;
import java.util.Set;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
/**
* @author Joram Barrez
*/
public interface BpmnParseHandler {
Set<Class<? extends BaseElement>> getHandledTypes();
void parse(BpmnParse bpmnParse, BaseElement element);
}
......@@ -217,6 +217,19 @@ public class TaskServiceTest extends PluggableActivitiTestCase {
((TaskServiceImpl) taskService).deleteComments(null, processInstanceId);
}
}
@Deployment(resources = { "org/activiti/engine/test/api/oneTaskProcess.bpmn20.xml" })
public void testRap() {
// Start a few process instances
for (int i=0; i<20; i++) {
processEngine.getRuntimeService().startProcessInstanceByKey("oneTaskProcess");
}
// See if there are tasks for kermit
List<Task> tasks = processEngine.getTaskService().createTaskQuery().list();
assertEquals(20, tasks.size());
}
public void testTaskDelegation() {
Task task = taskService.newTask();
......
......@@ -13,20 +13,25 @@
package org.activiti.standalone.parsing;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.AbstractBpmnParseListener;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler;
/**
* @author Frederik Heremans
* @author Joram Barrez
*/
public class TestBPMNParseListener extends AbstractBpmnParseListener {
public class TestBPMNParseHandler extends AbstractBpmnParseHandler<Process> {
@Override
public void parseProcess(Process process, ProcessDefinitionEntity processDefinition) {
protected Class< ? extends BaseElement> getHandledType() {
return Process.class;
}
protected void executeParse(BpmnParse bpmnParse, Process element) {
// Change the key of all deployed process-definitions
processDefinition.setKey(processDefinition.getKey() + "-modified");
bpmnParse.getCurrentProcessDefinition().setKey(bpmnParse.getCurrentProcessDefinition().getKey() + "-modified");
}
}
log4j.rootLogger=DEBUG, CA
log4j.rootLogger=INFO, CA
# ConsoleAppender
log4j.appender.CA=org.apache.log4j.ConsoleAppender
......@@ -6,5 +6,5 @@ log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern= %d{hh:MM:ss,SSS} [%t] %-5p %c %x - %m%n
log4j.logger.org.apache.ibatis.level=TRACE
log4j.logger.org.apache.ibatis.level=INFO
log4j.logger.javax.activation.level=INFO
......@@ -13,9 +13,9 @@
<!-- job executor configurations -->
<property name="jobExecutorActivate" value="false" />
<property name="preParseListeners">
<property name="postBpmnParseHandlers">
<list>
<bean class="org.activiti.standalone.parsing.TestBPMNParseListener" />
<bean class="org.activiti.standalone.parsing.TestBPMNParseHandler" />
</list>
</property>
......
......@@ -295,9 +295,9 @@ public class BusinessTripRequest implements Serializable {
Activiti can be hooked-up to the CDI event-bus. This allows us to be notified of process events using standard CDI event mechanisms.
In order to enable CDI event support for activiti, enable the corresponding parse listener in the configuration:
<programlisting>
&lt;property name=&quot;customPostBPMNParseListeners&quot;&gt;
&lt;property name=&quot;postBpmnParseHandlers&quot;&gt;
&lt;list&gt;
&lt;bean class=&quot;org.activiti.cdi.impl.event.CdiEventSupportBpmnParseListener&quot; /&gt;
&lt;bean class=&quot;org.activiti.cdi.impl.event.CdiEventSupportBpmnParseHandler&quot; /&gt;
&lt;/list&gt;
&lt;/property&gt;
</programlisting>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册