/** * Copyright (c) 2012-2016 Marsha Chechik, Alessio Di Sandro, Michalis Famelis, * Rick Salay. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alessio Di Sandro - Implementation. */ package edu.toronto.cs.se.mmint.mid.impl; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; import org.eclipse.emf.ecore.util.EObjectContainmentEList; import org.eclipse.emf.ecore.util.EObjectResolvingEList; import org.eclipse.emf.ecore.util.InternalEList; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.osgi.framework.Bundle; import edu.toronto.cs.se.mmint.MMINT; import edu.toronto.cs.se.mmint.MMINTException; import edu.toronto.cs.se.mmint.MIDTypeHierarchy; import edu.toronto.cs.se.mmint.MIDTypeRegistry; import edu.toronto.cs.se.mmint.mid.ExtendibleElement; import edu.toronto.cs.se.mmint.mid.MID; import edu.toronto.cs.se.mmint.mid.MIDLevel; import edu.toronto.cs.se.mmint.mid.MIDPackage; import edu.toronto.cs.se.mmint.mid.Model; import edu.toronto.cs.se.mmint.mid.ModelElement; import edu.toronto.cs.se.mmint.mid.ModelEndpoint; import edu.toronto.cs.se.mmint.mid.ModelOrigin; import edu.toronto.cs.se.mmint.mid.editor.Diagram; import edu.toronto.cs.se.mmint.mid.editor.Editor; import edu.toronto.cs.se.mmint.mid.operator.ConversionOperator; import edu.toronto.cs.se.mmint.mid.operator.Operator; import edu.toronto.cs.se.mmint.mid.reasoning.MIDConstraintChecker; import edu.toronto.cs.se.mmint.mid.relationship.BinaryModelRel; import edu.toronto.cs.se.mmint.mid.relationship.ModelRel; import edu.toronto.cs.se.mmint.mid.utils.FileUtils; import edu.toronto.cs.se.mmint.mid.utils.MIDRegistry; import edu.toronto.cs.se.mmint.mid.utils.MIDTypeFactory; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Model</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * </p> * <ul> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelImpl#getOrigin <em>Origin</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelImpl#getFileExtension <em>File Extension</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelImpl#getEditors <em>Editors</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelImpl#getModelElems <em>Model Elems</em>}</li> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelImpl#getConversionOperators <em>Conversion Operators</em>}</li> * </ul> * * @generated */ public class ModelImpl extends GenericElementImpl implements Model { /** * The default value of the '{@link #getOrigin() <em>Origin</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getOrigin() * @generated * @ordered */ protected static final ModelOrigin ORIGIN_EDEFAULT = ModelOrigin.IMPORTED; /** * The cached value of the '{@link #getOrigin() <em>Origin</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getOrigin() * @generated * @ordered */ protected ModelOrigin origin = ORIGIN_EDEFAULT; /** * The default value of the '{@link #getFileExtension() <em>File Extension</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getFileExtension() * @generated * @ordered */ protected static final String FILE_EXTENSION_EDEFAULT = null; /** * The cached value of the '{@link #getFileExtension() <em>File Extension</em>}' attribute. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getFileExtension() * @generated * @ordered */ protected String fileExtension = FILE_EXTENSION_EDEFAULT; /** * The cached value of the '{@link #getEditors() <em>Editors</em>}' reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getEditors() * @generated * @ordered */ protected EList<Editor> editors; /** * The cached value of the '{@link #getModelElems() <em>Model Elems</em>}' containment reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getModelElems() * @generated * @ordered */ protected EList<ModelElement> modelElems; /** * The cached value of the '{@link #getConversionOperators() <em>Conversion Operators</em>}' reference list. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getConversionOperators() * @generated * @ordered */ protected EList<ConversionOperator> conversionOperators; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected ModelImpl() { super(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return MIDPackage.Literals.MODEL; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public ModelOrigin getOrigin() { return origin; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setOrigin(ModelOrigin newOrigin) { ModelOrigin oldOrigin = origin; origin = newOrigin == null ? ORIGIN_EDEFAULT : newOrigin; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MIDPackage.MODEL__ORIGIN, oldOrigin, origin)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public String getFileExtension() { return fileExtension; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setFileExtension(String newFileExtension) { String oldFileExtension = fileExtension; fileExtension = newFileExtension; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MIDPackage.MODEL__FILE_EXTENSION, oldFileExtension, fileExtension)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<Editor> getEditors() { if (editors == null) { editors = new EObjectResolvingEList<Editor>(Editor.class, this, MIDPackage.MODEL__EDITORS); } return editors; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<ModelElement> getModelElems() { if (modelElems == null) { modelElems = new EObjectContainmentEList<ModelElement>(ModelElement.class, this, MIDPackage.MODEL__MODEL_ELEMS); } return modelElems; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EList<ConversionOperator> getConversionOperators() { if (conversionOperators == null) { conversionOperators = new EObjectResolvingEList<ConversionOperator>(ConversionOperator.class, this, MIDPackage.MODEL__CONVERSION_OPERATORS); } return conversionOperators; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Model getMetatype() { ExtendibleElement metatype = super.getMetatype(); return (metatype == null) ? null : (Model) metatype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Model getSupertype() { ExtendibleElement supertype = super.getSupertype(); return (supertype == null) ? null : (Model) supertype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public MID getMIDContainer() { return (MID) this.eContainer(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { switch (featureID) { case MIDPackage.MODEL__MODEL_ELEMS: return ((InternalEList<?>)getModelElems()).basicRemove(otherEnd, msgs); } return super.eInverseRemove(otherEnd, featureID, msgs); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) { case MIDPackage.MODEL__ORIGIN: return getOrigin(); case MIDPackage.MODEL__FILE_EXTENSION: return getFileExtension(); case MIDPackage.MODEL__EDITORS: return getEditors(); case MIDPackage.MODEL__MODEL_ELEMS: return getModelElems(); case MIDPackage.MODEL__CONVERSION_OPERATORS: return getConversionOperators(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @SuppressWarnings("unchecked") @Override public void eSet(int featureID, Object newValue) { switch (featureID) { case MIDPackage.MODEL__ORIGIN: setOrigin((ModelOrigin)newValue); return; case MIDPackage.MODEL__FILE_EXTENSION: setFileExtension((String)newValue); return; case MIDPackage.MODEL__EDITORS: getEditors().clear(); getEditors().addAll((Collection<? extends Editor>)newValue); return; case MIDPackage.MODEL__MODEL_ELEMS: getModelElems().clear(); getModelElems().addAll((Collection<? extends ModelElement>)newValue); return; case MIDPackage.MODEL__CONVERSION_OPERATORS: getConversionOperators().clear(); getConversionOperators().addAll((Collection<? extends ConversionOperator>)newValue); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eUnset(int featureID) { switch (featureID) { case MIDPackage.MODEL__ORIGIN: setOrigin(ORIGIN_EDEFAULT); return; case MIDPackage.MODEL__FILE_EXTENSION: setFileExtension(FILE_EXTENSION_EDEFAULT); return; case MIDPackage.MODEL__EDITORS: getEditors().clear(); return; case MIDPackage.MODEL__MODEL_ELEMS: getModelElems().clear(); return; case MIDPackage.MODEL__CONVERSION_OPERATORS: getConversionOperators().clear(); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case MIDPackage.MODEL__ORIGIN: return origin != ORIGIN_EDEFAULT; case MIDPackage.MODEL__FILE_EXTENSION: return FILE_EXTENSION_EDEFAULT == null ? fileExtension != null : !FILE_EXTENSION_EDEFAULT.equals(fileExtension); case MIDPackage.MODEL__EDITORS: return editors != null && !editors.isEmpty(); case MIDPackage.MODEL__MODEL_ELEMS: return modelElems != null && !modelElems.isEmpty(); case MIDPackage.MODEL__CONVERSION_OPERATORS: return conversionOperators != null && !conversionOperators.isEmpty(); } return super.eIsSet(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) { if (baseClass == ExtendibleElement.class) { switch (baseOperationID) { case MIDPackage.EXTENDIBLE_ELEMENT___GET_METATYPE: return MIDPackage.MODEL___GET_METATYPE; case MIDPackage.EXTENDIBLE_ELEMENT___GET_MID_CONTAINER: return MIDPackage.MODEL___GET_MID_CONTAINER; default: return super.eDerivedOperationID(baseOperationID, baseClass); } } return super.eDerivedOperationID(baseOperationID, baseClass); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException { switch (operationID) { case MIDPackage.MODEL___GET_METATYPE: return getMetatype(); case MIDPackage.MODEL___GET_SUPERTYPE: return getSupertype(); case MIDPackage.MODEL___GET_MID_CONTAINER: return getMIDContainer(); case MIDPackage.MODEL___CREATE_SUBTYPE__STRING_BOOLEAN: try { return createSubtype((String)arguments.get(0), (Boolean)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___DELETE_TYPE: try { deleteType(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___GET_EMF_TYPE_ROOT: try { return getEMFTypeRoot(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___OPEN_TYPE: try { openType(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___CREATE_INSTANCE__STRING_MID: try { return createInstance((String)arguments.get(0), (MID)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___CREATE_INSTANCE_EDITOR: try { return createInstanceEditor(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___CREATE_INSTANCE_AND_EDITOR__STRING_MID: try { return createInstanceAndEditor((String)arguments.get(0), (MID)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___IMPORT_INSTANCE__STRING_MID: try { return importInstance((String)arguments.get(0), (MID)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___IMPORT_INSTANCE_AND_EDITOR__STRING_MID: try { return importInstanceAndEditor((String)arguments.get(0), (MID)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___COPY_INSTANCE__MODEL_STRING_MID: try { return copyInstance((Model)arguments.get(0), (String)arguments.get(1), (MID)arguments.get(2)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___COPY_INSTANCE_AND_EDITOR__MODEL_STRING_BOOLEAN_MID: try { return copyInstanceAndEditor((Model)arguments.get(0), (String)arguments.get(1), (Boolean)arguments.get(2), (MID)arguments.get(3)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___DELETE_INSTANCE: try { deleteInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___DELETE_INSTANCE_AND_FILE: try { deleteInstanceAndFile(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___GET_EMF_INSTANCE_ROOT: try { return getEMFInstanceRoot(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___OPEN_INSTANCE: try { openInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___CREATE_WORKFLOW_INSTANCE__STRING_MID: try { return createWorkflowInstance((String)arguments.get(0), (MID)arguments.get(1)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL___DELETE_WORKFLOW_INSTANCE: try { deleteWorkflowInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } } return super.eInvoke(operationID, arguments); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public String toString() { if (eIsProxy()) return super.toString(); StringBuffer result = new StringBuffer(super.toString()); result.append(" (origin: "); result.append(origin); result.append(", fileExtension: "); result.append(fileExtension); result.append(')'); return result.toString(); } /** * Adds a subtype of this model type to the Type MID, together with an editor type for it. * * @param newModelType * The new model type to be added. * @param newModelTypeName * The name of the new model type. * @param isMetamodelExtension * True if the new model type is extending the supertype's metamodel, false otherwise. * @throws MMINTException * If the uri of the new model type is already registered in the Type MID. * @generated NOT */ protected void addSubtype(Model newModelType, String newModelTypeName, boolean isMetamodelExtension) throws MMINTException { MID typeMID = this.getMIDContainer(); super.addSubtype(newModelType, this, null, newModelTypeName); MIDTypeFactory.addModelType(newModelType, typeMID); newModelType.setOrigin(ModelOrigin.CREATED); if (isMetamodelExtension) { try { String newMetamodelUri = MIDTypeRegistry.getExtendedMetamodelPath(newModelType); if (newMetamodelUri == null) { // create new metamodel file, else we're just recreating this subtype at startup EPackage newEPackage = EcoreFactory.eINSTANCE.createEPackage(); newEPackage.setName(newModelTypeName.toLowerCase()); newEPackage.setNsPrefix(newModelTypeName.toLowerCase()); newEPackage.setNsURI(newModelType.getUri()); EAnnotation newEAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); newEAnnotation.setSource(EcorePackage.eNS_URI); EMap<String, String> newEAnnotationDetails = newEAnnotation.getDetails(); newEAnnotationDetails.put(MIDTypeFactory.ECORE_INVOCATION_DELEGATE, MIDTypeFactory.ECORE_PIVOT_URI); newEAnnotationDetails.put(MIDTypeFactory.ECORE_SETTING_DELEGATE, MIDTypeFactory.ECORE_PIVOT_URI); newEAnnotationDetails.put(MIDTypeFactory.ECORE_VALIDATION_DELEGATE, MIDTypeFactory.ECORE_PIVOT_URI); newEPackage.getEAnnotations().add(newEAnnotation); EClass newRootEClass = EcoreFactory.eINSTANCE.createEClass(); newRootEClass.setName(newModelTypeName); if (!MIDTypeHierarchy.isRootType(this)) { EClass rootEClass = (EClass) getEMFTypeRoot().getEClassifiers().get(0); newRootEClass.getESuperTypes().add(rootEClass); } newEPackage.getEClassifiers().add(newRootEClass); newMetamodelUri = newModelTypeName + "." + EcorePackage.eNAME; FileUtils.writeModelFileInState(newEPackage, newMetamodelUri); } newModelType.setFileExtension(MIDTypeFactory.ECORE_REFLECTIVE_FILE_EXTENSION); } catch (Exception e) { MMINTException.print(IStatus.WARNING, "Error creating extended metamodel file, fallback to no extension", e); newModelType.setFileExtension(getFileExtension()); isMetamodelExtension = false; } } else { newModelType.setFileExtension(getFileExtension()); } // create editors String newEditorTypeFragmentUri = newModelType.getName(), newEditorTypeName, newModelTypeUri = newModelType.getUri(), editorId, wizardId, wizardDialogClassName; for (Editor editorType : getEditors()) { if (isMetamodelExtension) { if (editorType instanceof Diagram) { continue; } newEditorTypeName = MMINT.ROOT_EDITOR_NAME; editorId = MMINT.ROOT_EDITOR_ID; wizardId = null; wizardDialogClassName = null; } else { newEditorTypeName = editorType.getName(); editorId = editorType.getId(); wizardId = editorType.getWizardId(); wizardDialogClassName = editorType.getWizardDialogClass(); } try { //TODO MMINT[EDITOR] a new editor is created instead of attaching existing ones //TODO MMINT[EDITOR] because I couldn't find a way then from an editor to understand which model was being created Editor newEditorType = editorType.createSubtype(newEditorTypeFragmentUri, newEditorTypeName, newModelTypeUri, editorId, wizardId, wizardDialogClassName); MIDTypeFactory.addModelTypeEditor(newEditorType, newModelType); if (isMetamodelExtension) { // reflective editor only newEditorType.getFileExtensions().clear(); newEditorType.getFileExtensions().add(MIDTypeFactory.ECORE_REFLECTIVE_FILE_EXTENSION); break; } } catch (MMINTException e) { // models created through this editor will have the supermodel as static type MIDTypeFactory.addModelTypeEditor(editorType, newModelType); } } } /** * @generated NOT */ public Model createSubtype(String newModelTypeName, boolean isMetamodelExtension) throws MMINTException { MMINTException.mustBeType(this); Model newModelType = super.createThisEClass(); this.addSubtype(newModelType, newModelTypeName, isMetamodelExtension); return newModelType; } /** * @generated NOT */ public void deleteType() throws MMINTException { MMINTException.mustBeType(this); MID typeMID = this.getMIDContainer(); // delete the "thing" for (ModelElement modelElemType : getModelElems()) { super.delete(modelElemType.getUri(), typeMID); } List<Editor> delEditorTypes = new ArrayList<Editor>(getEditors()); for (Editor delEditorType : delEditorTypes) { delEditorType.deleteType(); } super.delete(); typeMID.getModels().remove(this); String metamodelUri = MIDTypeRegistry.getExtendedMetamodelPath(this); if (metamodelUri != null) { FileUtils.deleteFile(metamodelUri, false); } // delete operator types that use this model type List<Operator> delOperatorTypes = new ArrayList<>(); for (Operator operatorType : typeMID.getOperators()) { for (ModelEndpoint inputModelTypeEndpoint : operatorType.getInputs()) { if (inputModelTypeEndpoint.getTargetUri().equals(getUri()) && !delOperatorTypes.contains(operatorType)) { delOperatorTypes.add(operatorType); } } for (ModelEndpoint outputModelTypeEndpoint : operatorType.getOutputs()) { if (outputModelTypeEndpoint.getTargetUri().equals(getUri()) && !delOperatorTypes.contains(operatorType)) { delOperatorTypes.add(operatorType); } } } for (Operator operatorType : delOperatorTypes) { operatorType.deleteType(); } // delete model relationship types that use this model type List<ModelRel> delModelRelTypes = new ArrayList<>(); List<ModelEndpoint> delModelTypeEndpoints = new ArrayList<>(); for (ModelRel modelRelType : typeMID.getModelRels()) { for (ModelEndpoint modelTypeEndpoint : modelRelType.getModelEndpoints()) { if (modelTypeEndpoint.getTargetUri().equals(getUri())) { if (modelRelType instanceof BinaryModelRel) { if (!delModelRelTypes.contains(modelRelType)) { delModelRelTypes.add(modelRelType); } } else { delModelTypeEndpoints.add(modelTypeEndpoint); } } } } for (ModelEndpoint modelTypeEndpoint : delModelTypeEndpoints) { modelTypeEndpoint.deleteType(true); } for (ModelRel modelRelType : delModelRelTypes) { modelRelType.deleteType(); } // delete the subtypes of the "thing" for (Model modelSubtype : MIDTypeHierarchy.getDirectSubtypes(this, typeMID)) { modelSubtype.deleteType(); } } /** * @generated NOT */ public EPackage getEMFTypeRoot() throws MMINTException { MMINTException.mustBeType(this); EPackage rootModelTypeObj; if (!isDynamic()) { // get package from registry rootModelTypeObj = EPackage.Registry.INSTANCE.getEPackage(getUri()); } else { String metamodelUri = MIDTypeRegistry.getExtendedMetamodelPath(this); if (metamodelUri != null) { // get package from metamodel file try { rootModelTypeObj = (EPackage) FileUtils.readModelFile(metamodelUri, false); } catch (Exception e) { throw new MMINTException("Error accessing the metamodel file for model type" + getUri(), e); } } else { // climb up light types rootModelTypeObj = getSupertype().getEMFTypeRoot(); } } return rootModelTypeObj; } /** * @generated NOT */ public void openType() throws Exception { MMINTException.mustBeType(this); Model modelType = this; List<String> metamodelPaths = new ArrayList<>(); /*TODO MMINT[EDITOR] Fix: * a) references to inherited metamodels not good in binary eclipse * b) open UML * c) abstract model types (related to a, need to climb) */ while (true) { if (modelType.isDynamic()) { String metamodelPath = MIDTypeRegistry.getExtendedMetamodelPath(modelType); if (metamodelPath != null) { // get metamodel file from mmint state area metamodelPaths.add(metamodelPath); break; } } else { // get metamodel files from bundle Bundle bundle = MIDTypeRegistry.getTypeBundle(modelType.getUri()); Enumeration<URL> metamodels = bundle.findEntries("/", "*" + MMINT.MODEL_FILEEXTENSION_SEPARATOR + EcorePackage.eNAME, true); List<String> tempMetamodelPaths = new ArrayList<>(); String tempMetamodelPath = null; while (metamodels.hasMoreElements()) { String metamodelPath = FileLocator.toFileURL(metamodels.nextElement()).getFile(); // heuristic to open just one metamodel with many in the same bundle if (FileUtils.getFileNameFromUri(metamodelPath).equalsIgnoreCase(modelType.getName())) { tempMetamodelPath = metamodelPath; break; } tempMetamodelPaths.add(metamodelPath); } if (tempMetamodelPath != null) { metamodelPaths.add(tempMetamodelPath); } else { metamodelPaths.addAll(tempMetamodelPaths); } break; } // climb up light types modelType = modelType.getSupertype(); } // open editors Model ecoreModelType = MIDTypeRegistry.getType(EcorePackage.eNS_URI); Editor ecoreEditorType = ecoreModelType.getEditors().get(0); for (String metamodelPath : metamodelPaths) { FileUtils.openEclipseEditor(metamodelPath, ecoreEditorType.getId(), false); //TODO MMINT[ECORE] Try to open ecore diagram //String metamodelDiagramPath = metamodelPath + GMFDiagramUtils.DIAGRAM_SUFFIX; } } /** * Adds a model instance of this model type to an Instance or Workflow MID, or simply adds additional info to the * model instance. * * @param newModel * The new model to be added. * @param newModelId * The id of the new model. * @param newModelName * The name of the new model. * @param origin * The origin of the new model. * @param fileExtension * The file extension of the new model. * @param midLevel * The kind of MID (Instance or Workflow) that could contain the new model, regardless of whether it is * or isn't going to be contained in one. * @param instanceMID * An Instance or Workflow MID, null if the model isn't going to be contained in one. * @throws MMINTException * If the id of the new model is already registered in the MID. * @generated NOT */ protected void addInstance(@NonNull Model newModel, @NonNull String newModelId, @NonNull String newModelName, @NonNull ModelOrigin origin, @NonNull String fileExtension, @NonNull MIDLevel midLevel, @Nullable MID instanceMID) throws MMINTException { if (instanceMID == null) { super.addBasicInstance(newModel, newModelId, newModelName, midLevel); } else { super.addInstance(newModel, newModelId, newModelName, instanceMID); instanceMID.getModels().add(newModel); } newModel.setOrigin(origin); newModel.setFileExtension(fileExtension); } /** * @generated NOT */ public Model createInstance(String newModelUri, MID instanceMID) throws MMINTException { MMINTException.mustBeType(this); Model newModel = super.createThisEClass(); this.addInstance( newModel, newModelUri, FileUtils.getFileNameFromUri(newModelUri), ModelOrigin.CREATED, FileUtils.getFileExtensionFromUri(newModelUri), MIDLevel.INSTANCES, instanceMID); return newModel; } /** * @generated NOT */ public Editor createInstanceEditor() throws MMINTException { MMINTException.mustBeInstance(this); MID instanceMID = this.getMIDContainer(); Editor newEditor = null; //TODO MMINT[EDITOR] prioritize editors list instead of running twice? // all diagrams are tried.. for (Editor diagramType : this.getMetatype().getEditors()) { if (!(diagramType instanceof Diagram)) { continue; } try { newEditor = diagramType.createInstance(getUri(), instanceMID); break; } catch (MMINTException e) { continue; } } // ..or first editor is used if (newEditor == null) { for (Editor editorType : this.getMetatype().getEditors()) { if (editorType instanceof Diagram) { continue; } newEditor = editorType.createInstance(getUri(), instanceMID); break; } } if (newEditor == null) { throw new MMINTException("No editor type found"); } getEditors().add(newEditor); return newEditor; } /** * @generated NOT */ public Model createInstanceAndEditor(String newModelUri, MID instanceMID) throws MMINTException { Model newModel = this.createInstance(newModelUri, instanceMID); if (instanceMID != null) { newModel.createInstanceEditor(); } return newModel; } /** * @generated NOT */ public Model importInstance(String modelUri, MID instanceMID) throws MMINTException { MMINTException.mustBeType(this); Model newModel = super.createThisEClass(); this.addInstance( newModel, modelUri, FileUtils.getFileNameFromUri(modelUri), ModelOrigin.IMPORTED, FileUtils.getFileExtensionFromUri(modelUri), MIDLevel.INSTANCES, instanceMID); return newModel; } /** * @generated NOT */ public Model importInstanceAndEditor(String modelUri, MID instanceMID) throws MMINTException { Model newModel = importInstance(modelUri, instanceMID); if (instanceMID != null) { newModel.createInstanceEditor(); } return newModel; } /** * @generated NOT */ public Model copyInstance(Model origModel, String newModelName, MID instanceMID) throws MMINTException { MMINTException.mustBeType(this); // copy model String newModelUri = FileUtils.replaceFileNameInUri(origModel.getUri(), newModelName); try { FileUtils.copyTextFileAndReplaceText( origModel.getUri(), newModelUri, origModel.getName() + MMINT.MODEL_FILEEXTENSION_SEPARATOR, newModelName + MMINT.MODEL_FILEEXTENSION_SEPARATOR, true); } catch (Exception e) { throw new MMINTException("Error copying model file"); } Model newModel = createInstance(newModelUri, instanceMID); return newModel; } /** * @generated NOT */ public Model copyInstanceAndEditor(Model origModel, String newModelName, boolean copyDiagram, MID instanceMID) throws MMINTException { Model newModel = copyInstance(origModel, newModelName, instanceMID); // copy diagrams if (copyDiagram) { for (Editor oldEditor : origModel.getEditors()) { if (oldEditor.getUri().equals(origModel.getUri())) { continue; } try { FileUtils.copyTextFileAndReplaceText( oldEditor.getUri(), FileUtils.replaceFileNameInUri(oldEditor.getUri(), newModelName), origModel.getName() + MMINT.MODEL_FILEEXTENSION_SEPARATOR, newModelName + MMINT.MODEL_FILEEXTENSION_SEPARATOR, true); } catch (Exception e) { MMINTException.print(IStatus.WARNING, "Error copying diagram file, skipping it", e); continue; } //TODO MMINT[UML] add support for notation extra file (e.g. in UML) } } newModel.createInstanceEditor(); return newModel; } /** * @generated NOT */ @Override public boolean validateInstanceType(ExtendibleElement type) throws MMINTException { MMINTException.mustBeInstance(this); MMINTException.mustBeType(type); return MIDConstraintChecker.checkModelConstraint(this, type.getConstraint()); } /** * @generated NOT */ @Override public boolean validateInstance() throws MMINTException { MMINTException.mustBeInstance(this); boolean validates = MIDConstraintChecker.checkModelConstraint(this, this.getConstraint()); return validates && this.validateInstanceType(this.getMetatype()); } /** * Deletes this model instance from an Instance or Workflow MID. * * @param instanceMID * The Instance or Workflow MID that contains the operator. * * @generated NOT */ protected void deleteInstance(MID instanceMID) { instanceMID.getModels().remove(this); } /** * @generated NOT */ public void deleteInstance() throws MMINTException { MMINTException.mustBeInstance(this); MID instanceMID = this.getMIDContainer(); // delete model elements for (ModelElement modelElem : this.getModelElems()) { super.delete(modelElem.getUri(), instanceMID); } // delete editors for (Editor editor : this.getEditors()) { editor.deleteInstance(); } super.delete(); this.deleteInstance(instanceMID); // delete operators that use this model Set<Operator> delOperators = MIDRegistry.getInputOutputOperators(this, instanceMID); for (Operator delOperator : delOperators) { delOperator.deleteInstance(); } // delete model relationships that use this model Set<BinaryModelRel> delModelRels = MIDRegistry.getConnectedBinaryModelRels(this, instanceMID); for (BinaryModelRel delModelRel : delModelRels) { delModelRel.deleteInstance(); } Set<ModelEndpoint> delModelEndpoints = MIDRegistry.getConnectedNaryModelRelEndpoints(this, instanceMID); for (ModelEndpoint delModelEndpoint : delModelEndpoints) { delModelEndpoint.deleteInstance(true); } } /** * @generated NOT */ public void deleteInstanceAndFile() throws MMINTException { MMINTException.mustBeInstance(this); for (Editor editor : this.getEditors()) { FileUtils.deleteFile(editor.getUri(), true); } FileUtils.deleteFile(this.getUri(), true); this.deleteInstance(); } /** * @generated NOT */ public EObject getEMFInstanceRoot() throws MMINTException { MMINTException.mustBeInstance(this); EObject rootModelObj; try { rootModelObj = FileUtils.readModelFile(this.getUri(), true); } catch (Exception e) { throw new MMINTException("Error accessing the model file for model " + getUri(), e); } return rootModelObj; } /** * @generated NOT */ public void openInstance() throws Exception { MMINTException.mustBeInstance(this); Editor editor = this.getEditors().get(0); FileUtils.openEclipseEditor(editor.getUri(), editor.getId(), true); } /** * @generated NOT */ public Model createWorkflowInstance(String newModelId, MID workflowMID) throws MMINTException { MMINTException.mustBeType(this); Model newModel = super.createThisEClass(); this.addInstance( newModel, newModelId, newModelId, ModelOrigin.CREATED, this.getFileExtension(), MIDLevel.WORKFLOWS, workflowMID); return newModel; } /** * @generated NOT */ public void deleteWorkflowInstance() throws MMINTException { MMINTException.mustBeWorkflow(this); MID workflowMID = this.getMIDContainer(); super.delete(); this.deleteInstance(workflowMID); workflowMID.getModels().remove(this); // delete operators that use this model Set<Operator> delOperators = MIDRegistry.getInputOutputOperators(this, workflowMID); for (Operator delOperator : delOperators) { delOperator.deleteWorkflowInstance(); } // delete model relationships that use this model Set<BinaryModelRel> delModelRels = MIDRegistry.getConnectedBinaryModelRels(this, workflowMID); for (BinaryModelRel delModelRel : delModelRels) { delModelRel.deleteWorkflowInstance(); } Set<ModelEndpoint> delModelEndpoints = MIDRegistry.getConnectedNaryModelRelEndpoints(this, workflowMID); for (ModelEndpoint delModelEndpoint : delModelEndpoints) { delModelEndpoint.deleteWorkflowInstance(); } } } //ModelImpl