blob: 3cb847a94b75055246ab9e0863bebb6c426eb78a [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2012 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* CEA LIST - Initial API and implementation
* Jeremie Tatibouet (CEA LIST) - Apply fix for Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
*
*****************************************************************************/
package org.eclipse.papyrus.moka.fuml.Semantics.impl.Classes.Kernel;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IStructuredValue;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IValue;
import org.eclipse.papyrus.moka.fuml.Semantics.Classes.Kernel.IFeatureValue;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.InstanceSpecification;
import org.eclipse.uml2.uml.InstanceValue;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Slot;
import org.eclipse.uml2.uml.StructuralFeature;
import org.eclipse.uml2.uml.UMLFactory;
import org.eclipse.uml2.uml.ValueSpecification;
public abstract class StructuredValue extends Value implements IStructuredValue {
@Override
public ValueSpecification specify() {
// Return an instance value that specifies this structured value.
// Debug.println("[specify] StructuredValue...");
InstanceValue instanceValue = UMLFactory.eINSTANCE.createInstanceValue();
InstanceSpecification instance = UMLFactory.eINSTANCE.createInstanceSpecification();
instanceValue.setType(null);
instanceValue.setInstance(instance);
instance.getClassifiers().addAll(this.getTypes());
List<IFeatureValue> featureValues = this.getFeatureValues();
// Debug.println("[specify] " + featureValues.size() + " feature(s).");
for (int i = 0; i < featureValues.size(); i++) {
IFeatureValue featureValue = featureValues.get(i);
Slot slot = UMLFactory.eINSTANCE.createSlot();
slot.setDefiningFeature(featureValue.getFeature());
// Debug.println("[specify] feature = " + featureValue.feature.name
// + ", " + featureValue.values.size() + " value(s).");
List<IValue> values = featureValue.getValues();
for (int j = 0; j < values.size(); j++) {
IValue value = values.get(j);
// Debug.println("[specify] value = " + value);
slot.getValues().add(value.specify());
}
instance.getSlots().add(slot);
}
return instanceValue;
}
public void addFeatureValues(List<IFeatureValue> oldFeatureValues) {
// Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
// 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.
List<Classifier> types = this.getTypes();
for (int i = 0; i < types.size(); i++) {
Classifier type = types.get(i);
this.addFeatureValuesForType(type, oldFeatureValues);
}
}
public void addFeatureValuesForType(Classifier type, List<IFeatureValue> oldFeatureValues) {
// Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
// 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.)
List<NamedElement> ownedMembers = type.getOwnedMembers();
for (int j = 0; j < ownedMembers.size(); j++) {
NamedElement ownedMember = ownedMembers.get(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.)
List<Classifier> supertypes = type.getGenerals();
for (int i = 0; i < supertypes.size(); i++) {
Classifier supertype = supertypes.get(i);
this.addFeatureValuesForType(supertype, oldFeatureValues);
}
}
public void createFeatureValues() {
// Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
// 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 ArrayList<IFeatureValue>());
}
public List<IFeatureValue> getMemberValues() {
// Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
// 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.)
List<IFeatureValue> featureValues = this.getFeatureValues();
List<IFeatureValue> memberValues = new ArrayList<IFeatureValue>();
List<Classifier> types = this.getTypes();
for (int i = 0; i < featureValues.size(); i++) {
IFeatureValue featureValue = featureValues.get(i);
Boolean isMember = false;
int j = 1;
while (j <= types.size() & !isMember) {
Classifier type = types.get(j - 1);
List<NamedElement> members = type.getMembers();
int k = 1;
while (k <= members.size() & !isMember) {
NamedElement member = members.get(k - 1);
isMember = featureValue.getFeature() == member;
k = k + 1;
}
j = j + 1;
}
if (isMember) {
memberValues.add(featureValue);
}
}
return memberValues;
}
public List<IValue> getValues(NamedElement feature, List<IFeatureValue> featureValues) {
// Issue FUML12-20 Feature values need to be created for private structural features of parent classifiers
// 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.
IFeatureValue foundFeatureValue = null;
int i = 1;
while (foundFeatureValue == null & i <= featureValues.size()) {
IFeatureValue featureValue = featureValues.get(i - 1);
if (featureValue.getFeature() == feature) {
foundFeatureValue = featureValue;
}
i = i + 1;
}
List<IValue> values;
if (foundFeatureValue == null) {
values = new ArrayList<IValue>();
} else {
values = foundFeatureValue.getValues();
}
return values;
}
public abstract IFeatureValue getFeatureValue(StructuralFeature feature);
public abstract void setFeatureValue(StructuralFeature feature, List<IValue> values, Integer position);
public abstract List<IFeatureValue> getFeatureValues();
}