
org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of activiti-engine Show documentation
Show all versions of activiti-engine Show documentation
workflow engine base on bboss and activiti.
The newest version!
/* 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.Collection;
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.Artifact;
import org.activiti.bpmn.model.Association;
import org.activiti.bpmn.model.BaseElement;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.DataSpec;
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.data.Data;
import org.activiti.engine.impl.bpmn.data.DataRef;
import org.activiti.engine.impl.bpmn.data.IOSpecification;
import org.activiti.engine.impl.bpmn.data.ItemDefinition;
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;
/**
* @author Joram Barrez
*/
public abstract class AbstractBpmnParseHandler 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> getHandledTypes() {
Set> types = new HashSet>();
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 activitiListenerList, ScopeImpl scope) {
for (ActivitiListener activitiListener : activitiListenerList) {
scope.addExecutionListener(activitiListener.getEvent(), createExecutionListener(bpmnParse, activitiListener));
}
}
protected void createExecutionListenersOnTransition(BpmnParse bpmnParse, List 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 eventDefinitions = (List) scope.getProperty(PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION);
if(eventDefinitions == null) {
eventDefinitions = new ArrayList();
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;
}
protected IOSpecification createIOSpecification(BpmnParse bpmnParse, org.activiti.bpmn.model.IOSpecification specificationModel) {
IOSpecification ioSpecification = new IOSpecification();
for (DataSpec dataInputElement : specificationModel.getDataInputs()) {
ItemDefinition itemDefinition = bpmnParse.getItemDefinitions().get(dataInputElement.getItemSubjectRef());
Data dataInput = new Data(bpmnParse.getTargetNamespace() + ":" + dataInputElement.getId(), dataInputElement.getId(), itemDefinition);
ioSpecification.addInput(dataInput);
}
for (DataSpec dataOutputElement : specificationModel.getDataOutputs()) {
ItemDefinition itemDefinition = bpmnParse.getItemDefinitions().get(dataOutputElement.getItemSubjectRef());
Data dataOutput = new Data(bpmnParse.getTargetNamespace() + ":" + 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 void processArtifacts(BpmnParse bpmnParse, Collection artifacts, ScopeImpl scope) {
// associations
for (Artifact artifact : artifacts) {
if (artifact instanceof Association) {
createAssociation(bpmnParse, (Association) artifact, scope);
}
}
}
protected void createAssociation(BpmnParse bpmnParse, Association association, ScopeImpl parentScope) {
BpmnModel bpmnModel = bpmnParse.getBpmnModel();
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(BpmnParse.PROPERTYNAME_COMPENSATION_HANDLER_ID, targetActivity.getId());
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy