package gov.nasa.jpl.mbee.mdk.systems_reasoner.actions; import com.nomagic.magicdraw.copypaste.CopyPasting; import com.nomagic.magicdraw.core.Application; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*; import com.nomagic.uml2.ext.magicdraw.compositestructures.mdinternalstructures.Connector; import gov.nasa.jpl.mbee.mdk.systems_reasoner.actions.CreateSpecializedTypeAction; import gov.nasa.jpl.mbee.mdk.validation.GenericRuleViolationAction; import java.util.ArrayList; import java.util.List; public class SetOrCreateRedefinableElementAction extends GenericRuleViolationAction { /** * */ private static final long serialVersionUID = 1L; private static final String DEFAULT_NAME = "Redefine Attribute"; private Classifier subClassifier; private RedefinableElement re; private boolean recursion; private String name; private boolean isIndividual; public SetOrCreateRedefinableElementAction(final Classifier clazz, final RedefinableElement re, boolean isIndividual) { this(clazz, re, false, DEFAULT_NAME, isIndividual); } /** * @param targetForRedefEl * @param elementToBeRedefined * @param recursion * @param name * @param isIndividual */ public SetOrCreateRedefinableElementAction(final Classifier targetForRedefEl, final RedefinableElement elementToBeRedefined, final boolean recursion, final String name, boolean isIndividual) { super(name); this.subClassifier = targetForRedefEl; this.re = elementToBeRedefined; this.recursion = recursion; this.name = name; this.isIndividual = isIndividual; } public SetOrCreateRedefinableElementAction(Classifier specific, RedefinableElement elementToBeRedefined, List<RedefinableElement> traveled, boolean recursionMode, String name, boolean individualMode) { super(name); this.subClassifier = specific; this.re = elementToBeRedefined; this.recursion = recursionMode; this.name = name; this.isIndividual = individualMode; } public static RedefinableElement redefineAttribute(final Classifier subClassifier, final RedefinableElement re, final boolean createSpecializedType, boolean isIndividual) { return redefineAttribute(subClassifier, re, createSpecializedType, new ArrayList<RedefinableElement>(), new ArrayList<Classifier>(), isIndividual); } public static RedefinableElement redefineAttribute(final Classifier classifierOfProp, final RedefinableElement elementToBeRedefined, final boolean createSpecializedType, final List<RedefinableElement> traveled, List<Classifier> visited, boolean isIndividual) { if (elementToBeRedefined.isLeaf()) { Application.getInstance().getGUILog().log(elementToBeRedefined.getQualifiedName() + " is a leaf. Cannot redefine further."); } if (!classifierOfProp.isEditable()) { Application.getInstance().getGUILog().log(classifierOfProp.getQualifiedName() + " is not editable. Skipping redefinition."); return null; } RedefinableElement redefinedElement = null; for (NamedElement p : classifierOfProp.getOwnedMember()) { System.out.println("Handling: " + p.getName() + " and " + elementToBeRedefined.getName()); if (p instanceof RedefinableElement && ((RedefinableElement) p).getRedefinedElement().contains(elementToBeRedefined)) { redefinedElement = (RedefinableElement) p; break; } else if (p instanceof RedefinableElement && ((RedefinableElement) p).getRedefinedElement().isEmpty()) { if (isMatchingStructuralFeature(p, elementToBeRedefined)) { redefinedElement = (RedefinableElement) p; redefinedElement.getRedefinedElement().add(elementToBeRedefined); break; } else if (p instanceof Connector && elementToBeRedefined instanceof Connector) { if (((Connector) p).getEnd() != null && ((Connector) elementToBeRedefined).getEnd() != null) { if (((Connector) p).getEnd().get(0).getRole() != null && ((Connector) elementToBeRedefined).getEnd().get(0).getRole() != null) { if (isMatchingStructuralFeature(((Connector) p).getEnd().get(0).getRole(), (((Connector) elementToBeRedefined).getEnd().get(0).getRole()))) { if (((Connector) p).getEnd().size() > 1) { if (isMatchingStructuralFeature(((Connector) p).getEnd().get(1).getRole(), (((Connector) elementToBeRedefined).getEnd().get(1).getRole()))) { redefinedElement = (RedefinableElement) p; redefinedElement.getRedefinedElement().add(elementToBeRedefined); break; } } } } } else { Application.getInstance().getGUILog().log("[WARNING] Behavioral Features (Operations and Receptions) are not handled."); } } } } if (redefinedElement == null) { redefinedElement = (RedefinableElement) CopyPasting.copyPasteElement(elementToBeRedefined, classifierOfProp, false); redefinedElement.getRedefinedElement().add(elementToBeRedefined); } if (createSpecializedType && redefinedElement instanceof Property && ((TypedElement) redefinedElement).getType() != null) { // SpecializeStructureAction speca = new SpecializeStructureAction(classifierOfProp, false, "", isIndividual, isIndividual); // speca.createSpecialClassifier() CreateSpecializedTypeAction.createSpecializedType((Property) redefinedElement, classifierOfProp, true, traveled, visited, isIndividual); } return redefinedElement; // else { // Application.getInstance().getGUILog().log(elementToBeRedefined.getQualifiedName() + " has already been redefined in " + classifierOfProp.getQualifiedName() + "."); // return null; // } } private static boolean isMatchingStructuralFeature(NamedElement p, NamedElement elementToBeRedefined) { if (p.getName().equals(elementToBeRedefined.getName())) { if (p instanceof TypedElement && elementToBeRedefined instanceof TypedElement) { if (((TypedElement) p).getType() != null) { if (((TypedElement) p).getType().equals(((TypedElement) elementToBeRedefined).getType())) { return true; } } else if (((TypedElement) elementToBeRedefined).getType() == null) { return true; } } } return false; } @Override public void run() { redefineAttribute(subClassifier, re, recursion, isIndividual); } @Override public String getName() { return name; } @Override public String getSessionName() { return "redefine attribute"; } }