Specification: Semantics of a Foundation Subset for Executable UML Models, FTF Beta 1 (ptc/08-11-03)
Section: 7.4.2.2.2 ActivityEdge, 7.4.2.2.4 ActivityNode & A.5.2 List Add
Summary:
The fUML execution engine in clause 8 and the fUML reference implementation [1] are both written according to the Java => bUML mapping specified in appendix A of the fUML specification.
Unfortunately, this Java => bUML mapping does not take into account the different kinds of containers used fUML because the ListAdd operation (A.5.2) is defined to be the Java equivalent of fUML AddStructuralFeature Value
{isReplaceAll=false}
.
This creates a problem in several places where fUML class attributes are defined to be unique; in particular:
7.4.2.2.2 ActivityEdge::source
{unique}
7.4.2.2.2 ActivityEdge::target {unique}
7.4.2.2.4 ActivityNode::incoming
{unique}
7.4.2.2.4 ActivityNode::outgoing {unique}
The fUML reference implementation [1] loads an fUML model by CMOF reflection.
This means that it processes each activity edge in three parts:
1. The activity node at the source of the edge
2. The activity node at the target of the edge
3. The edge itself
#1 and #3 lead to a duplication of the same edge on the outgoing list of the source node.
#2 and #3 lead to a duplication of the same edge on the incoming list of the target node.
[1] http://portal.modeldriven.org/content/foundational-uml-reference-implementation
Proposed resolution:
The fUML specification should update the Java => bUML mapping to account for the different kinds of containers used for fUML.
The fUML reference implementation should be updated according to the revised Java => bUML mapping for collections.
A workaround to this issue for the reference implementation in [1] involves modifying fUML.Syntax.Activities.IntermediateActivities.ActivityEdge as follows:
public void setTarget(fUML.Syntax.Activities.IntermediateActivities.ActivityNode target) {
this.target = target;
/**
- Because the reference implementation "constructs" the fUML.Syntax model by reflection from the XMI,
- it turns out that activity edges get a duplication of their source pins because:
- - once by reflection when creating the ActivityNode whose .incoming edges includes this instance.
- - a second time this ActivityEdge is constructed by reflection.
*/
if (!target.incoming.contains(this))
{
target.incoming.addValue(this);
}
else
{
Debug.println("ActivityEdge[" + this.name + "].setTarget(target) this edge is already included in the incoming edge list for target: " + target.getClass().getCanonicalName()+"[" + target.name + "]");
}
}
public void setSource(fUML.Syntax.Activities.IntermediateActivities.ActivityNode source) {
this.source = source;
/**
- Because the reference implementation "constructs" the fUML.Syntax model by reflection from the XMI,
- it turns out that activity edges get a duplication of their source pins because:
- - once by reflection when creating the ActivityNode whose .outgoing edges includes this instance.
- - a second time this ActivityEdge is constructed by reflection.
*/
if (! source.outgoing.contains(this))
{
source.outgoing.addValue(this);
}
else
{
Debug.println("ActivityEdge[" + this.name + "].setSource(target) this edge is already included in the outgoing edge list for target: " + source.getClass().getCanonicalName()+"[" + source.name + "]");
}
}