All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fUML.Semantics.Actions.IntermediateActions.AddStructuralFeatureValueActionActivation Maven / Gradle / Ivy

Go to download

This open source software is a reference implementation, consisting of software and related files, for the OMG specification called the Semantics of a Foundational Subset for Executable UML Models (fUML). The reference implementation is intended to implement the execution semantics of UML activity models, accepting an XMI file from a conformant UML model as its input and providing an execution trace of the selected activity model(s) as its output. The core execution engine, which is directly generated from the normative syntactic and semantic models for fUML, may also be used as a library implementation of fUML in other software.

There is a newer version: 1.5.0a
Show newest version

/*
 * 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy