package gov.nasa.jpl.mbee.mdk.systems_reasoner.actions; import com.nomagic.magicdraw.annotation.Annotation; import com.nomagic.magicdraw.core.Application; import com.nomagic.uml2.ext.magicdraw.classes.mdkernel.*; import gov.nasa.jpl.mbee.mdk.validation.GenericRuleViolationAction; import java.util.*; public class CreateInstanceAction extends GenericRuleViolationAction { private static final long serialVersionUID = 1L; private static final String DEFAULT_NAME = "Create Instance"; private Classifier classifier; private Element context; private String name; private boolean createSlots; private InstanceSpecification instance; private static int safetyNet; private static Map<Property, InstanceSpecification> createdInstances = new HashMap<Property, InstanceSpecification>(); public CreateInstanceAction(final Classifier classifier, final Element context, final boolean createSlots) { this(classifier, context, createSlots, DEFAULT_NAME); } public CreateInstanceAction(final Classifier classifier, final Element context, final boolean createSlots, String name) { super(name); this.classifier = classifier; this.context = context; this.createSlots = createSlots; } public static InstanceSpecification createInstance(final Element instanceable, final Element context, final boolean createSlots) { safetyNet = 0; return createInstance(instanceable, context, createSlots, new HashMap<Classifier, InstanceSpecification>()); } public static InstanceSpecification createInstance(final Element instanceable, final Element context, final boolean createSlots, final Map<Classifier, InstanceSpecification> traveled) { final Classifier classifier; if (instanceable instanceof Classifier) { createdInstances.clear(); classifier = (Classifier) instanceable; } else if (instanceable instanceof Property && ((Property) instanceable).getType() instanceof Classifier) { classifier = (Classifier) ((Property) instanceable).getType(); } else { return null; } if (classifier.isAbstract()) { Application.getInstance().getGUILog().log(classifier.getQualifiedName() + " is marked as abstract. Skipping instantiation."); return null; } //System.out.println("Instancing " + ((Property) instanceable).getQualifiedName() + " | Traveled: " + traveled.size()); if (traveled.containsKey(classifier)) { Application.getInstance().getGUILog().log("Caught circular reference for " + ((Property) instanceable).getQualifiedName() + ". Skipping instantiation and applying circular reference."); return traveled.get(classifier); //return null; } System.out.println("Classifier: " + classifier.getQualifiedName()); String prefix = ""; Element owner = context; if (context instanceof InstanceSpecification) { prefix = ((InstanceSpecification) context).getName() + "."; owner = context.getOwner(); } final InstanceSpecification instance = Application.getInstance().getProject().getElementsFactory().createInstanceSpecificationInstance(); traveled.put(classifier, instance); /*if (instanceable instanceof Property) { traveled.put((Property) instanceable, instance); System.out.println("Adding to traveled: " + ((Property) instanceable).getQualifiedName() + " [" + traveled.size() + "]"); }*/ instance.setName(prefix + (instanceable instanceof Property ? ((Property) instanceable).getName() : classifier.getName())); instance.getClassifier().add(classifier); if (!owner.canAdd(instance)) { Application.getInstance().getGUILog().log("Cannot add instance specification to " + (owner instanceof NamedElement ? ((NamedElement) owner).getQualifiedName() : owner) + "."); return null; } instance.setOwner(owner); final List<NamedElement> inheritedMembers = new ArrayList<NamedElement>(); inheritedMembers.addAll(classifier.getInheritedMember()); /*if (safetyNet++ > 1000) { Application.getInstance().getGUILog().log("Exceeded safety net max instantiations. Aborting..."); throw new RuntimeException("Show me stack"); //return instance; }*/ if (createSlots) { //final Map<Property, InstanceSpecification> clonedMap = new HashMap<Property, InstanceSpecification>(traveled); //System.out.println("Clone size: " + clonedMap.size()); CreateSlotsAction.createSlots(instance, createSlots, new HashMap<Classifier, InstanceSpecification>(traveled)); } return instance; } @Override public void run() { instance = createInstance(classifier, context, createSlots); } @Override public void execute(Collection<Annotation> annotations) { super.execute(annotations); ValidateAction.validate(instance); } @Override public String getName() { return name; } @Override public String getSessionName() { return name; } }