package gov.nasa.jpl.mbee.mdk.systems_reasoner.actions;
import com.nomagic.magicdraw.copypaste.CopyPasting;
import com.nomagic.magicdraw.core.Application;
import com.nomagic.magicdraw.openapi.uml.SessionManager;
import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Instance2BSTAction extends SRAction {
/**
*
*/
private static final long serialVersionUID = 1L;
public static final String DEFAULT_ID = "Convert Instance to BST";
public List<InstanceSpecification> instances;
public Instance2BSTAction(List<InstanceSpecification> instances) {
super(DEFAULT_ID);
this.instances = instances;
}
@Override
public void actionPerformed(ActionEvent e) {
SessionManager.getInstance().createSession(DEFAULT_ID);
for (final InstanceSpecification instance : instances) {
if (!instance.hasClassifier()) {
Application.getInstance().getGUILog().log("Instance " + instance.getQualifiedName() + " has no classifiers. Skipping BST conversion.");
continue;
}
instance2BST(instance);
}
SessionManager.getInstance().closeSession();
}
public static Classifier instance2BST(final InstanceSpecification instance) {
return instance2BST(instance, null, null, new HashMap<InstanceSpecification, Classifier>());
}
public static Classifier instance2BST(final InstanceSpecification instance, final InstanceSpecification lastInstance, final Element owner, final Map<InstanceSpecification, Classifier> traveled) {
if (traveled.containsKey(instance)) {
//Application.getInstance().getGUILog().log("Detected circular reference: " + instance.getQualifiedName() + ". Skipping conversion.");
return traveled.get(instance);
}
//System.out.println("Traveled to " + instance.getQualifiedName());
//traveled.put(instance);
final Classifier classifier = instance.getClassifier().get(0);
final Classifier specific = (Classifier) CopyPasting.copyPasteElement(classifier, instance.getOwner(), true);
for (final Generalization generalization : specific.getGeneralization()) {
generalization.dispose();
}
for (final NamedElement ne : specific.getOwnedMember()) {
ne.dispose();
}
for (final Classifier c : instance.getClassifier()) {
SpecializeClassifierAction.specialize(specific, c);
}
if (owner != null && owner.canAdd(specific)) {
specific.setOwner(owner);
}
traveled.put(instance, specific);
specific.setName(lastInstance != null && instance.getName().startsWith(lastInstance.getName() + ".") ? instance.getName().replaceFirst(lastInstance.getName() + ".", "") : instance.getName());
specific.setName(specific.getName().substring(0, 1).toUpperCase() + specific.getName().substring(1, specific.getName().length()));
for (final Slot slot : instance.getSlot()) {
if (slot.getDefiningFeature() instanceof Property) {
final Property property = (Property) slot.getDefiningFeature();
final Property redefinedAttribute = (Property) SetOrCreateRedefinableElementAction.redefineAttribute(specific, property, false, true);
if (!slot.hasValue()) {
continue;
}
if (slot.getValue().size() == 1) {
final ValueSpecification value = slot.getValue().get(0);
processAttribute(redefinedAttribute, value, instance, specific, traveled);
//Application.getInstance().getGUILog().log("Slot " + slot.getOwningInstance().getQualifiedName() + "::" + slot.getDefiningFeature().getName() + " has more than one value. Only applying the first to converted BST default value.");
}
else {
for (final ValueSpecification value : slot.getValue()) {
final Property subsettingProperty = Application.getInstance().getProject().getElementsFactory().createPropertyInstance();
subsettingProperty.setOwner(specific);
processAttribute(subsettingProperty, value, instance, specific, traveled);
if (subsettingProperty.getType() != null && subsettingProperty.getType() instanceof Classifier) {
final String name = subsettingProperty.getType().getName();
subsettingProperty.setName((name.substring(0, 1).toLowerCase() + name.substring(1, name.length())).replaceAll(" ", ""));
}
subsettingProperty.getSubsettedProperty().add(redefinedAttribute);
}
}
}
}
return specific;
}
public static Property processAttribute(final Property property, final ValueSpecification value, final InstanceSpecification lastInstance, final Element owner, final Map<InstanceSpecification, Classifier> traveled) {
//final ValueSpecification value = slot.getValue().get(0);
if (value instanceof InstanceValue && ((InstanceValue) value).getInstance() != null) {
final Classifier nestedClassifier = instance2BST(((InstanceValue) value).getInstance(), lastInstance, owner, traveled);
property.setType(nestedClassifier);
}
else if (value instanceof ElementValue && ((ElementValue) value).getElement() instanceof Classifier) {
property.setType((Classifier) ((ElementValue) value).getElement());
}
else {
final ValueSpecification defaultValue = (ValueSpecification) CopyPasting.copyPasteElement(value, null, false);
property.setDefaultValue(defaultValue);
}
return null;
}
}