/* 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.camunda.bpm.model.bpmn.impl.instance;
import org.camunda.bpm.model.bpmn.BpmnModelException;
import org.camunda.bpm.model.bpmn.Query;
import org.camunda.bpm.model.bpmn.builder.AbstractFlowNodeBuilder;
import org.camunda.bpm.model.bpmn.impl.QueryImpl;
import org.camunda.bpm.model.bpmn.instance.FlowElement;
import org.camunda.bpm.model.bpmn.instance.FlowNode;
import org.camunda.bpm.model.bpmn.instance.SequenceFlow;
import org.camunda.bpm.model.xml.ModelBuilder;
import org.camunda.bpm.model.xml.impl.instance.ModelTypeInstanceContext;
import org.camunda.bpm.model.xml.instance.ModelElementInstance;
import org.camunda.bpm.model.xml.type.ModelElementTypeBuilder;
import org.camunda.bpm.model.xml.type.attribute.Attribute;
import org.camunda.bpm.model.xml.type.child.SequenceBuilder;
import org.camunda.bpm.model.xml.type.reference.AttributeReference;
import org.camunda.bpm.model.xml.type.reference.ElementReferenceCollection;
import org.camunda.bpm.model.xml.type.reference.Reference;
import java.util.Collection;
import java.util.HashSet;
import static org.camunda.bpm.model.bpmn.impl.BpmnModelConstants.*;
/**
* The BPMN flowNode element
*
* @author Sebastian Menski
*/
public abstract class FlowNodeImpl extends FlowElementImpl implements FlowNode {
protected static ElementReferenceCollection<SequenceFlow, Incoming> incomingCollection;
protected static ElementReferenceCollection<SequenceFlow, Outgoing> outgoingCollection;
/** Camunda Attributes */
protected static Attribute<Boolean> camundaAsyncAfter;
protected static Attribute<Boolean> camundaAsyncBefore;
protected static Attribute<Boolean> camundaExclusive;
protected static Attribute<String> camundaJobPriority;
public static void registerType(ModelBuilder modelBuilder) {
ModelElementTypeBuilder typeBuilder = modelBuilder.defineType(FlowNode.class, BPMN_ELEMENT_FLOW_NODE)
.namespaceUri(BPMN20_NS)
.extendsType(FlowElement.class)
.abstractType();
SequenceBuilder sequenceBuilder = typeBuilder.sequence();
incomingCollection = sequenceBuilder.elementCollection(Incoming.class)
.qNameElementReferenceCollection(SequenceFlow.class)
.build();
outgoingCollection = sequenceBuilder.elementCollection(Outgoing.class)
.qNameElementReferenceCollection(SequenceFlow.class)
.build();
/** Camunda Attributes */
camundaAsyncAfter = typeBuilder.booleanAttribute(CAMUNDA_ATTRIBUTE_ASYNC_AFTER)
.namespace(CAMUNDA_NS)
.defaultValue(false)
.build();
camundaAsyncBefore = typeBuilder.booleanAttribute(CAMUNDA_ATTRIBUTE_ASYNC_BEFORE)
.namespace(CAMUNDA_NS)
.defaultValue(false)
.build();
camundaExclusive = typeBuilder.booleanAttribute(CAMUNDA_ATTRIBUTE_EXCLUSIVE)
.namespace(CAMUNDA_NS)
.defaultValue(true)
.build();
camundaJobPriority = typeBuilder.stringAttribute(CAMUNDA_ATTRIBUTE_JOB_PRIORITY)
.namespace(CAMUNDA_NS)
.build();
typeBuilder.build();
}
public FlowNodeImpl(ModelTypeInstanceContext context) {
super(context);
}
@SuppressWarnings("rawtypes")
public AbstractFlowNodeBuilder builder() {
throw new BpmnModelException("No builder implemented for type " + getElementType().getTypeNamespace() +":" + getElementType().getTypeName());
}
@SuppressWarnings("rawtypes")
public void updateAfterReplacement() {
super.updateAfterReplacement();
Collection<Reference> incomingReferences = getIncomingReferencesByType(SequenceFlow.class);
for (Reference<?> reference : incomingReferences) {
for (ModelElementInstance sourceElement : reference.findReferenceSourceElements(this)) {
String referenceIdentifier = reference.getReferenceIdentifier(sourceElement);
if (referenceIdentifier != null && referenceIdentifier.equals(getId()) && reference instanceof AttributeReference) {
String attributeName = ((AttributeReference) reference).getReferenceSourceAttribute().getAttributeName();
if (attributeName.equals(BPMN_ATTRIBUTE_SOURCE_REF)) {
getOutgoing().add((SequenceFlow) sourceElement);
}
else if (attributeName.equals(BPMN_ATTRIBUTE_TARGET_REF)) {
getIncoming().add((SequenceFlow) sourceElement);
}
}
}
}
}
public Collection<SequenceFlow> getIncoming() {
return incomingCollection.getReferenceTargetElements(this);
}
public Collection<SequenceFlow> getOutgoing() {
return outgoingCollection.getReferenceTargetElements(this);
}
public Query<FlowNode> getPreviousNodes() {
Collection<FlowNode> previousNodes = new HashSet<FlowNode>();
for (SequenceFlow sequenceFlow : getIncoming()) {
previousNodes.add(sequenceFlow.getSource());
}
return new QueryImpl<FlowNode>(previousNodes);
}
public Query<FlowNode> getSucceedingNodes() {
Collection<FlowNode> succeedingNodes = new HashSet<FlowNode>();
for (SequenceFlow sequenceFlow : getOutgoing()) {
succeedingNodes.add(sequenceFlow.getTarget());
}
return new QueryImpl<FlowNode>(succeedingNodes);
}
/** Camunda Attributes */
public boolean isCamundaAsyncBefore() {
return camundaAsyncBefore.getValue(this);
}
public void setCamundaAsyncBefore(boolean isCamundaAsyncBefore) {
camundaAsyncBefore.setValue(this, isCamundaAsyncBefore);
}
public boolean isCamundaAsyncAfter() {
return camundaAsyncAfter.getValue(this);
}
public void setCamundaAsyncAfter(boolean isCamundaAsyncAfter) {
camundaAsyncAfter.setValue(this, isCamundaAsyncAfter);
}
public boolean isCamundaExclusive() {
return camundaExclusive.getValue(this);
}
public void setCamundaExclusive(boolean isCamundaExclusive) {
camundaExclusive.setValue(this, isCamundaExclusive);
}
public String getCamundaJobPriority() {
return camundaJobPriority.getValue(this);
}
public void setCamundaJobPriority(String jobPriority) {
camundaJobPriority.setValue(this, jobPriority);
}
}