Issue 18721: RemoveStructuralFeatureValueAction: Removal of links does not consider provided input value (fuml-rtf) Source: LieberLieber Software (Mrs. Tanja Mayerhofer, mayerhofer(at)big.tuwien.ac.at.) Nature: Clarification Severity: Minor Summary: In the case a RemoveStructuralFeatureValueAction is used to remove a link, the provided input value is not taken into account but only the object owning the defined association end. However, the UML standard states: “If the feature is an association end, the semantics are the same as for destroying links, the participants of which are the object owning the structural feature and the value being removed.” Thus, only links between the provided object (object pin) and value (value pin) should be considered. The following code could be a resolution to this issue: public class RemoveStructuralFeatureValueActionActivation extends fUML.Semantics.Actions.IntermediateActions.WriteStructuralFeatureActionActivation { public void doAction() { ... if (association != null) { LinkList links = this.getMatchingLinks(association, feature, value); >>> if(inputValue != null) { >>> Property oppositeEnd = this.getOppositeEnd(association, feature); >>> LinkList linksMatchingInputValue = this.getMatchingLinks(association, oppositeEnd, inputValue); >>> links = linksMatchingInputValue; } ... } } Resolution: Update RemoveStructuralFeatureValueActionActivation The issue is correct about the problem. However, the suggested solution would not work properly. As suggested, in the case that inputValue != null, the set of matching links previously found is replaced by a list of links that have the correct value for the action's structural feature. But these links will no longer necessarily have the action's object value as their opposite end value. What is needed is for matching links to have both the current opposite end value and, if inputValue != null, the correct near end value. Revised Text: In 8.6.3.1, Figure 8.33, and the normative XMI, add the following operation to class StructuralFeatureActionActivation: getMatchingLinksForEndValue( association : Association, end : StructuralFeature, oppositeValue : Value, endValue : Value [0..1] ) : Link [*] In 8.6.3.2.12 RemoveStructuralFeatureValueActionActivation, in the if clause of the third if statement (beginning if (association != null)), in the first statement, replace the call this.getMatchingLinks(association, feature, value) with this.getMatchingLinksForEndValue(association, feature, value, inputValue) In 8.6.3.2.13 StructuralFeatureActionActivation, replace the body of the operation getMatchingLinks (after the comment) with return this.getMatchingLinksForEndValue(association, end, oppositeValue, null); Add the following operation after getMatchingLinks, and renumber subsequent operations accordingly, [3] getMatchingLinksForEndValue ( in association : Association, in end : StructuralFeature, in oppositeValue : Value, in endValue : Value [0..1] ) : Link [0..*] // Get the links of the given binary association whose end opposite // to the given end has the given opposite value and, optionally, that // has a given end value for the given end. Property oppositeEnd = this.getOppositeEnd(association, end); ExtensionalValueList extent = this.getExecutionLocus().getExtent( association); LinkList links = new LinkList(); for (int i = 0; i < extent.size(); i++) { ExtensionalValue link = extent.getValue(i); if (link.getFeatureValue(oppositeEnd).values.getValue(0).equals(oppositeValue)) { boolean matches = true; if (endValue != null) { matches = link.getFeatureValue(end).values.getValue(0).equals(endValue); } if (matches) { if (!end.multiplicityElement.isOrdered | links.size() == 0) { links.addValue((Link) link); } else { int n = link.getFeatureValue(end).position; boolean continueSearching = true; int j = 0; while (continueSearching & j < links.size()) { j = j + 1; continueSearching = links.getValue(j - 1).getFeatureValue(end).position < n; } if (continueSearching) { links.addValue((Link) link); } else { links.addValue(j - 1, (Link) link); } } } } } return links; Actions taken: May 16, 2013: received issue October 8, 2015: Resolved December 22, 2015: closed issue Discussion: End of Annotations:===== m: webmaster@omg.org Date: 16 May 2013 09:58:49 -0400 To: Subject: Issue/Bug Report X-Brightmail-Tracker: AAAAAA== X-Brightmail-Tracker: AAAAAA== ******************************************************************************* Name: Tanja Mayerhofer Employer: Vienna University of Technology mailFrom: mayerhofer@big.tuwien.ac.at Terms_Agreement: I agree Specification: Semantics of a Foundational Subset for Executable UML Models (FUML) Section: 8.6.3.2.12 RemoveStructuralFeatureValueActionActivation FormalNumber: ptc/2012-10-18 Version: 1.1 Doc_Year: Year Doc_Month: Month Doc_Day: Day Page: 306-309 Title: RemoveStructuralFeatureValueAction: Removal of links does not consider provided input value Nature: Clarification Severity: Minor CODE: 3TMw8 B1: Report Issue Remote Name: hopper.ifs.tuwien.ac.at Remote User: HTTP User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0 Time: 09:58 AM Description: In the case a RemoveStructuralFeatureValueAction is used to remove a link, the provided input value is not taken into account but only the object owning the defined association end. However, the UML standard states: .If the feature is an association end, the semantics are the same as for destroying links, the participants of which are the object owning the structural feature and the value being removed.. Thus, only links between the provided object (object pin) and value (value pin) should be considered. The following code could be a resolution to this issue: public class RemoveStructuralFeatureValueActionActivation extends fUML.Semantics.Actions.IntermediateActions.WriteStructuralFeatureActionActivation { public void doAction() { ... if (association != null) { LinkList links = this.getMatchingLinks(association, feature, value); >>> if(inputValue != null) { >>> Property oppositeEnd = this.getOppositeEnd(association, feature); >>> LinkList linksMatchingInputValue = this.getMatchingLinks(association, oppositeEnd, inputValue); >>> links = linksMatchingInputValue; } ... } }