/*
* Initial version copyright 2008 Lockheed Martin Corporation, except
* as stated in the file entitled Licensing-Information.
*
* All modifications copyright 2009-2015 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.Classes.Kernel;
import fUML.Debug;
import UMLPrimitiveTypes.*;
import fUML.Syntax.*;
import fUML.Syntax.Classes.Kernel.*;
import fUML.Semantics.*;
import fUML.Semantics.Loci.*;
public abstract class StructuredValue extends
fUML.Semantics.Classes.Kernel.Value {
public fUML.Syntax.Classes.Kernel.ValueSpecification specify() {
// Return an instance value that specifies this structured value.
// Debug.println("[specify] StructuredValue...");
InstanceValue instanceValue = new InstanceValue();
InstanceSpecification instance = new InstanceSpecification();
instanceValue.type = null;
instanceValue.instance = instance;
instance.classifier = this.getTypes();
FeatureValueList featureValues = this.getFeatureValues();
// Debug.println("[specify] " + featureValues.size() + " feature(s).");
for (int i = 0; i < featureValues.size(); i++) {
FeatureValue featureValue = featureValues.getValue(i);
Slot slot = new Slot();
slot.definingFeature = featureValue.feature;
// Debug.println("[specify] feature = " + featureValue.feature.name
// + ", " + featureValue.values.size() + " value(s).");
ValueList values = featureValue.values;
for (int j = 0; j < values.size(); j++) {
Value value = values.getValue(j);
// Debug.println("[specify] value = " + value);
slot.value.addValue(value.specify());
}
instance.slot.addValue(slot);
}
return instanceValue;
} // specify
public abstract fUML.Semantics.Classes.Kernel.FeatureValue getFeatureValue(
fUML.Syntax.Classes.Kernel.StructuralFeature feature);
public abstract void setFeatureValue(
fUML.Syntax.Classes.Kernel.StructuralFeature feature,
fUML.Semantics.Classes.Kernel.ValueList values, int position);
public abstract fUML.Semantics.Classes.Kernel.FeatureValueList getFeatureValues();
public fUML.Semantics.Classes.Kernel.FeatureValueList getMemberValues() {
// Return the feature values for this structured value that are for structural
// features that are members of one of the types of the structured value.
// (That is, they are owned are inherited, excluding private features of
// supertypes that are not inherited.)
FeatureValueList featureValues = this.getFeatureValues();
FeatureValueList memberValues = new FeatureValueList();
ClassifierList types = this.getTypes();
for (int i = 0; i < featureValues.size(); i++) {
FeatureValue featureValue = featureValues.getValue(i);
Boolean isMember = false;
int j = 1;
while (j <= types.size() & !isMember) {
Classifier type = types.getValue(j-1);
NamedElementList members = type.member;
int k = 1;
while (k <= members.size() & !isMember) {
NamedElement member = members.getValue(k-1);
isMember = featureValue.feature == member;
k = k + 1;
}
j = j + 1;
}
if (isMember) {
memberValues.addValue(featureValue);
}
}
return memberValues;
};
public void createFeatureValues() {
// Create empty feature values for all structural features of the types
// of this structured value and all its supertypes (including private
// features that are not inherited).
this.addFeatureValues(new FeatureValueList());
}
public void addFeatureValues(FeatureValueList oldFeatureValues) {
// Add feature values for all structural features of the types
// of this structured value and all its supertypes (including private
// features that are not inherited). If a feature has an old feature
// value in the given list, then use that to initialize the values of
// the corresponding new feature value. Otherwise leave the values of
// the new feature value empty.
ClassifierList types = this.getTypes();
for (int i = 0; i < types.size(); i++) {
Classifier type = types.getValue(i);
this.addFeatureValuesForType(type, oldFeatureValues);
}
}
public void addFeatureValuesForType(Classifier type, FeatureValueList oldFeatureValues) {
// Add feature values for all structural features of the given type and
// all of its supertypes (including private features that are not
// inherited). If a feature has an old feature value in the given list,
// then use that to initialize the values of the corresponding new
// feature value. Otherwise leave the values of the new feature value
// empty.
// Set feature values for the owned structural features of the given
// type. (Any common structural values that have already been added
// previously will simply have their values set again.)
NamedElementList ownedMembers = type.ownedMember;
for (int j = 0; j < ownedMembers.size(); j++) {
NamedElement ownedMember = ownedMembers.getValue(j);
if (ownedMember instanceof StructuralFeature) {
this.setFeatureValue((StructuralFeature) ownedMember,
this.getValues(ownedMember, oldFeatureValues), 0);
}
}
// Add feature values for the structural features of the supertypes
// of the given type. (Note that the feature values for supertype
// features always come after the feature values for owned features.)
ClassifierList supertypes = type.general;
for (int i = 0; i < supertypes.size(); i++) {
Classifier supertype = supertypes.getValue(i);
this.addFeatureValuesForType(supertype, oldFeatureValues);
}
}
public ValueList getValues(NamedElement feature, FeatureValueList featureValues) {
// Return the values from the feature value in the given list for the
// given feature. If there is no such feature value, return an empty
// list.
FeatureValue foundFeatureValue = null;
int i = 1;
while (foundFeatureValue == null & i <= featureValues.size()) {
FeatureValue featureValue = featureValues.getValue(i-1);
if (featureValue.feature == feature) {
foundFeatureValue = featureValue;
}
i = i + 1;
}
ValueList values;
if (foundFeatureValue == null) {
values = new ValueList();
} else {
values = foundFeatureValue.values;
}
return values;
}
} // StructuredValue