/* * Initial version copyright 2008 Lockheed Martin Corporation, except * as stated in the file entitled Licensing-Information. * * All modifications copyright 2009-2012 Data Access Technologies, Inc. * * Licensed under the Academic Free License version 3.0 * (http://www.opensource.org/licenses/afl-3.0.php), except as stated * in the file entitled Licensing-Information. */ package fUML.Semantics.Actions.IntermediateActions; import fUML.Debug; import UMLPrimitiveTypes.*; import fUML.Syntax.*; import fUML.Syntax.Classes.Kernel.*; import fUML.Syntax.CommonBehaviors.BasicBehaviors.*; import fUML.Syntax.CommonBehaviors.Communications.*; import fUML.Syntax.Activities.IntermediateActivities.*; import fUML.Syntax.Actions.BasicActions.*; import fUML.Syntax.Actions.IntermediateActions.*; import fUML.Semantics.*; import fUML.Semantics.Classes.Kernel.*; import fUML.Semantics.CommonBehaviors.BasicBehaviors.*; import fUML.Semantics.Activities.IntermediateActivities.*; import fUML.Semantics.Actions.BasicActions.*; import fUML.Semantics.Loci.LociL1.*; public class AddStructuralFeatureValueActionActivation extends fUML.Semantics.Actions.IntermediateActions.WriteStructuralFeatureActionActivation { public void doAction() { // Get the values of the object and value input pins. // If the given feature is an association end, then create a link // between the object and value inputs. // Otherwise, if the object input is a structural value, then add a // value to the values for the feature. // If isReplaceAll is true, first remove all current matching links or // feature values. // If isReplaceAll is false and there is an insertAt pin, insert the // value at the appropriate position. AddStructuralFeatureValueAction action = (AddStructuralFeatureValueAction) (this.node); StructuralFeature feature = action.structuralFeature; Association association = this.getAssociation(feature); Value value = this.takeTokens(action.object).getValue(0); ValueList inputValues = this.takeTokens(action.value); // NOTE: Multiplicity of the value input pin is required to be 1..1. Value inputValue = inputValues.getValue(0); int insertAt = 0; if (action.insertAt != null) { insertAt = ((UnlimitedNaturalValue) this .takeTokens(action.insertAt).getValue(0)).value.naturalValue; } if (association != null) { LinkList links = this.getMatchingLinks(association, feature, value); Property oppositeEnd = this.getOppositeEnd(association, feature); int position = 0; if (oppositeEnd.multiplicityElement.isOrdered) { position = this.getMatchingLinks(association, oppositeEnd, inputValue).size() + 1; } if (action.isReplaceAll) { for (int i = 0; i < links.size(); i++) { Link link = links.getValue(i); link.destroy(); } } else if (feature.multiplicityElement.isUnique) { int i = 1; boolean destroyed = false; while (!destroyed & i <= links.size()) { Link link = links.getValue(i - 1); FeatureValue featureValue = link.getFeatureValue(feature); if (featureValue.values.getValue(0).equals(inputValue)) { position = link.getFeatureValue(oppositeEnd).position; link.destroy(); destroyed = true; } i = i + 1; } } Link newLink = new Link(); newLink.type = association; newLink.setFeatureValue(feature, inputValues, insertAt); ValueList oppositeValues = new ValueList(); oppositeValues.addValue(value); newLink.setFeatureValue(oppositeEnd, oppositeValues, position); newLink.addTo(this.getExecutionLocus()); } else if (value instanceof StructuredValue) { // If the value is a data value, then it must be copied before // any change is made. if (!(value instanceof Reference)) { value = value.copy(); } StructuredValue structuredValue = (StructuredValue) value; if (action.isReplaceAll) { structuredValue.setFeatureValue(feature, inputValues, 0); } else { FeatureValue featureValue = structuredValue .getFeatureValue(feature); if (featureValue.values.size() > 0 & insertAt == 0) { // *** If there is no insertAt pin, then the structural // feature must be unordered, and the insertion position is // immaterial. *** insertAt = ((ChoiceStrategy) this.getExecutionLocus().factory .getStrategy("choice")).choose(featureValue.values .size()); } if (feature.multiplicityElement.isUnique) { // Remove any existing value that duplicates the input value int j = position(inputValue, featureValue.values, 1); if (j > 0) { featureValue.values.remove(j - 1); } } if (insertAt <= 0) { // Note: insertAt = -1 indicates an // unlimited value of "*" featureValue.values.addValue(inputValue); } else { featureValue.values.addValue(insertAt - 1, inputValue); } } } if (action.result != null) { this.putToken(action.result, value); } } // doAction } // AddStructuralFeatureValueActionActivation