/** * 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 org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.impl.ENotificationImpl; 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.mid.EMFInfo; 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.relationship.ModelElementReference; import edu.toronto.cs.se.mmint.mid.relationship.ModelEndpointReference; 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; import edu.toronto.cs.se.mmint.mid.utils.PrimitiveEObjectWrapper; /** * <!-- begin-user-doc --> * An implementation of the model object '<em><b>Model Element</b></em>'. * <!-- end-user-doc --> * <p> * The following features are implemented: * </p> * <ul> * <li>{@link edu.toronto.cs.se.mmint.mid.impl.ModelElementImpl#getEInfo <em>EInfo</em>}</li> * </ul> * * @generated */ public class ModelElementImpl extends ExtendibleElementImpl implements ModelElement { /** * The cached value of the '{@link #getEInfo() <em>EInfo</em>}' containment reference. * <!-- begin-user-doc --> * <!-- end-user-doc --> * @see #getEInfo() * @generated * @ordered */ protected EMFInfo eInfo; /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ protected ModelElementImpl() { super(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override protected EClass eStaticClass() { return MIDPackage.Literals.MODEL_ELEMENT; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public EMFInfo getEInfo() { return eInfo; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public NotificationChain basicSetEInfo(EMFInfo newEInfo, NotificationChain msgs) { EMFInfo oldEInfo = eInfo; eInfo = newEInfo; if (eNotificationRequired()) { ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, MIDPackage.MODEL_ELEMENT__EINFO, oldEInfo, newEInfo); if (msgs == null) msgs = notification; else msgs.add(notification); } return msgs; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public void setEInfo(EMFInfo newEInfo) { if (newEInfo != eInfo) { NotificationChain msgs = null; if (eInfo != null) msgs = ((InternalEObject)eInfo).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - MIDPackage.MODEL_ELEMENT__EINFO, null, msgs); if (newEInfo != null) msgs = ((InternalEObject)newEInfo).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - MIDPackage.MODEL_ELEMENT__EINFO, null, msgs); msgs = basicSetEInfo(newEInfo, msgs); if (msgs != null) msgs.dispatch(); } else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, MIDPackage.MODEL_ELEMENT__EINFO, newEInfo, newEInfo)); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public ModelElement getMetatype() { ExtendibleElement metatype = super.getMetatype(); return (metatype == null) ? null : (ModelElement) metatype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public ModelElement getSupertype() { ExtendibleElement supertype = super.getSupertype(); return (supertype == null) ? null : (ModelElement) supertype; } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public MID getMIDContainer() { return (MID) this.eContainer().eContainer(); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { switch (featureID) { case MIDPackage.MODEL_ELEMENT__EINFO: return basicSetEInfo(null, 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_ELEMENT__EINFO: return getEInfo(); } return super.eGet(featureID, resolve, coreType); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eSet(int featureID, Object newValue) { switch (featureID) { case MIDPackage.MODEL_ELEMENT__EINFO: setEInfo((EMFInfo)newValue); return; } super.eSet(featureID, newValue); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public void eUnset(int featureID) { switch (featureID) { case MIDPackage.MODEL_ELEMENT__EINFO: setEInfo((EMFInfo)null); return; } super.eUnset(featureID); } /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ @Override public boolean eIsSet(int featureID) { switch (featureID) { case MIDPackage.MODEL_ELEMENT__EINFO: return eInfo != null; } 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_ELEMENT___GET_METATYPE; case MIDPackage.EXTENDIBLE_ELEMENT___GET_MID_CONTAINER: return MIDPackage.MODEL_ELEMENT___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_ELEMENT___GET_METATYPE: return getMetatype(); case MIDPackage.MODEL_ELEMENT___GET_SUPERTYPE: return getSupertype(); case MIDPackage.MODEL_ELEMENT___GET_MID_CONTAINER: return getMIDContainer(); case MIDPackage.MODEL_ELEMENT___CREATE_TYPE_REFERENCE__MODELELEMENTREFERENCE_BOOLEAN_MODELENDPOINTREFERENCE: try { return createTypeReference((ModelElementReference)arguments.get(0), (Boolean)arguments.get(1), (ModelEndpointReference)arguments.get(2)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___CREATE_SUBTYPE_AND_REFERENCE__MODELELEMENTREFERENCE_STRING_STRING_EMFINFO_MODELENDPOINTREFERENCE: try { return createSubtypeAndReference((ModelElementReference)arguments.get(0), (String)arguments.get(1), (String)arguments.get(2), (EMFInfo)arguments.get(3), (ModelEndpointReference)arguments.get(4)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___DELETE_TYPE: try { deleteType(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___GET_EMF_TYPE_OBJECT: try { return getEMFTypeObject(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___CREATE_INSTANCE_REFERENCE__MODELENDPOINTREFERENCE: try { return createInstanceReference((ModelEndpointReference)arguments.get(0)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___CREATE_INSTANCE_AND_REFERENCE__STRING_STRING_EMFINFO_MODELENDPOINTREFERENCE: try { return createInstanceAndReference((String)arguments.get(0), (String)arguments.get(1), (EMFInfo)arguments.get(2), (ModelEndpointReference)arguments.get(3)); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___DELETE_INSTANCE: try { deleteInstance(); return null; } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } case MIDPackage.MODEL_ELEMENT___GET_EMF_INSTANCE_OBJECT: try { return getEMFInstanceObject(); } catch (Throwable throwable) { throw new InvocationTargetException(throwable); } } return super.eInvoke(operationID, arguments); } /** * @generated NOT */ public ModelElementReference createTypeReference(ModelElementReference modelElemTypeRef, boolean isModifiable, ModelEndpointReference containerModelTypeEndpointRef) throws MMINTException { MMINTException.mustBeType(this); ModelElementReference newModelElemTypeRef = super.createThisReferenceEClass(); super.addTypeReference(newModelElemTypeRef, modelElemTypeRef, isModifiable, false); containerModelTypeEndpointRef.getModelElemRefs().add(newModelElemTypeRef); return newModelElemTypeRef; } /** * @generated NOT */ public ModelElementReference createSubtypeAndReference(ModelElementReference modelElemTypeRef, String newModelElemTypeUri, String newModelElemTypeName, EMFInfo eInfo, ModelEndpointReference containerModelTypeEndpointRef) throws MMINTException { MMINTException.mustBeType(this); ModelRel modelRelType = (ModelRel) containerModelTypeEndpointRef.eContainer(); MID typeMID = modelRelType.getMIDContainer(); ModelElement newModelElemType = typeMID.getExtendibleElement(newModelElemTypeUri); if (newModelElemType == null) { // create the "thing" newModelElemType = super.createThisEClass(); super.addSubtype(newModelElemType, newModelElemTypeUri, newModelElemTypeName); MIDTypeFactory.addModelElementType(newModelElemType, eInfo, containerModelTypeEndpointRef.getObject().getTarget()); } // create the reference of the "thing" ModelElementReference newModelElemTypeRef = newModelElemType.createTypeReference(modelElemTypeRef, true, containerModelTypeEndpointRef); // create references of the "thing" in subtypes of the container for (ModelRel modelRelSubtype : MIDTypeHierarchy.getSubtypes(modelRelType, typeMID)) { ModelEndpointReference containerModelSubtypeEndpointRef = MIDRegistry.getReference(containerModelTypeEndpointRef, modelRelSubtype.getModelEndpointRefs()); ModelElementReference modelElemSubtypeRef = null; if (modelElemTypeRef != null) { ModelEndpointReference modelSubtypeRefSuper = MIDRegistry.getReference((ModelEndpointReference) modelElemTypeRef.eContainer(), modelRelSubtype.getModelEndpointRefs()); modelElemSubtypeRef = MIDRegistry.getReference(modelElemTypeRef, modelSubtypeRefSuper.getModelElemRefs()); } newModelElemType.createTypeReference(modelElemSubtypeRef, false, containerModelSubtypeEndpointRef); } return newModelElemTypeRef; } /** * @generated NOT */ public void deleteType() throws MMINTException { MMINTException.mustBeType(this); super.delete(); //TODO MMINT[OO] might need to implement full removal } /** * @generated NOT */ public ENamedElement getEMFTypeObject() throws MMINTException { MMINTException.mustBeType(this); ENamedElement modelTypeObj; try { modelTypeObj = (ENamedElement) FileUtils.readModelObject(getUri(), ((Model) eContainer()).getEMFTypeRoot().eResource()); } catch (Exception e) { throw new MMINTException("Error accessing metamodel file", e); } return modelTypeObj; } /** * @generated NOT */ public ModelElementReference createInstanceReference(ModelEndpointReference containerModelEndpointRef) throws MMINTException { MMINTException.mustBeInstance(this); ModelElementReference newModelElemRef = super.createThisReferenceEClass(); super.addInstanceReference(newModelElemRef, false); containerModelEndpointRef.getModelElemRefs().add(newModelElemRef); return newModelElemRef; } /** * @generated NOT */ public ModelElementReference createInstanceAndReference(String newModelElemUri, String newModelElemName, EMFInfo eInfo, ModelEndpointReference containerModelEndpointRef) throws MMINTException { MMINTException.mustBeType(this); MID instanceMID = containerModelEndpointRef.getMIDContainer(); ModelElement newModelElem = null; newModelElemUri += MMINT.ROLE_SEPARATOR + getUri(); if (instanceMID != null) { // can be null when the containing model rel is not stored in the MID newModelElem = instanceMID.getExtendibleElement(newModelElemUri); } if (newModelElem == null) { newModelElem = super.createThisEClass(); //TODO MMINT[MAP] When input and output come from different mids, is it not correct to store the extendible map entry in the output if (instanceMID == null) { super.addBasicInstance(newModelElem, newModelElemUri, newModelElemName, MIDLevel.INSTANCES); } else { super.addInstance(newModelElem, newModelElemUri, newModelElemName, instanceMID); } newModelElem.setEInfo(eInfo); containerModelEndpointRef.getObject().getTarget().getModelElems().add(newModelElem); } ModelElementReference newModelElemRef = newModelElem.createInstanceReference(containerModelEndpointRef); return newModelElemRef; } /** * @generated NOT */ public void deleteInstance() throws MMINTException { MMINTException.mustBeInstance(this); super.delete(); //TODO MMINT[OO] might need to implement full removal } /** * @generated NOT */ public EObject getEMFInstanceObject() throws MMINTException { MMINTException.mustBeInstance(this); String modelElemUri = getUri().substring(0, getUri().indexOf(MMINT.ROLE_SEPARATOR)); int lastSegmentIndex = modelElemUri.lastIndexOf(MMINT.URI_SEPARATOR); String lastSegment = modelElemUri.substring(lastSegmentIndex + 1, modelElemUri.length()); boolean isPrimitive = !lastSegment.startsWith(MIDRegistry.ECORE_EREFERENCE_URI_PREFIX); if (isPrimitive) { modelElemUri = modelElemUri.substring(0, lastSegmentIndex); } EObject modelObj; try { modelObj = FileUtils.readModelObject(modelElemUri, null); } catch (Exception e) { throw new MMINTException("Error accessing the model file for model element" + getUri(), e); } if (isPrimitive) { EObject modelObjOwner = modelObj; EStructuralFeature feature = modelObjOwner.eClass().getEStructuralFeature(lastSegment); modelObj = new PrimitiveEObjectWrapper(modelObjOwner, feature, modelObjOwner.eGet(feature)); } return modelObj; } } //ModelElementImpl