diff options
Diffstat (limited to 'core/org.eclipse.emf.teneo.annotations/src/org/eclipse/emf/teneo/annotations/pamodel/impl/PAnnotatedModelImpl.java')
-rwxr-xr-x | core/org.eclipse.emf.teneo.annotations/src/org/eclipse/emf/teneo/annotations/pamodel/impl/PAnnotatedModelImpl.java | 684 |
1 files changed, 684 insertions, 0 deletions
diff --git a/core/org.eclipse.emf.teneo.annotations/src/org/eclipse/emf/teneo/annotations/pamodel/impl/PAnnotatedModelImpl.java b/core/org.eclipse.emf.teneo.annotations/src/org/eclipse/emf/teneo/annotations/pamodel/impl/PAnnotatedModelImpl.java new file mode 100755 index 000000000..3039d85aa --- /dev/null +++ b/core/org.eclipse.emf.teneo.annotations/src/org/eclipse/emf/teneo/annotations/pamodel/impl/PAnnotatedModelImpl.java @@ -0,0 +1,684 @@ +/** + * <copyright> + * </copyright> + * + * $Id: PAnnotatedModelImpl.java,v 1.30 2010/08/18 13:17:49 mtaal Exp $ + */ +package org.eclipse.emf.teneo.annotations.pamodel.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.notify.impl.AdapterImpl; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EModelElement; +import org.eclipse.emf.ecore.ENamedElement; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.util.InternalEList; +import org.eclipse.emf.ecore.xmi.XMLResource; +import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEAttribute; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEDataType; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEModelElement; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEPackage; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEReference; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEStructuralFeature; +import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel; +import org.eclipse.emf.teneo.annotations.pamodel.PamodelPackage; +import org.eclipse.emf.teneo.annotations.pannotation.SequenceGenerator; +import org.eclipse.emf.teneo.annotations.pannotation.SequenceStyleGenerator; +import org.eclipse.emf.teneo.annotations.pannotation.TableGenerator; + +/** + * <!-- begin-user-doc --> An implementation of the model object ' + * <em><b>PAnnotated Model</b></em>'. <!-- end-user-doc --> + * <p> + * The following features are implemented: + * <ul> + * <li>{@link org.eclipse.emf.teneo.annotations.pamodel.impl.PAnnotatedModelImpl#getPaEPackages <em>Pa EPackages</em>}</li> + * </ul> + * </p> + * + * @generated + */ +public class PAnnotatedModelImpl extends EObjectImpl implements PAnnotatedModel { + + @SuppressWarnings("unchecked") + class MapTrackingAdapter extends AdapterImpl { + @Override + public void notifyChanged(Notification msg) { + // TODO handle resolve? + Object msgFeature = msg.getFeature(); + if (!msg.isTouch() + && msgFeature == PamodelPackage.eINSTANCE + .getPAnnotatedEModelElement_ModelElement()) { + switch (msg.getEventType()) { + case Notification.SET: + case Notification.UNSET: + removeMapping((EModelElement) msg.getOldValue()); + addMapping((PAnnotatedEModelElement) msg.getNotifier()); + break; + } + } else if (msgFeature instanceof EReference && !msg.isTouch()) { + EReference r = (EReference) msgFeature; + if (PamodelPackage.eINSTANCE.getPAnnotatedEModelElement() + .isSuperTypeOf(r.getEReferenceType()) + && r.isContainment()) { + switch (msg.getEventType()) { + case Notification.UNSET: + case Notification.SET: + if (msg.getOldValue() != null) { + detach((PAnnotatedEModelElement) msg.getOldValue()); + } + if (msg.getNewValue() != null) { + attach((PAnnotatedEModelElement) msg.getNewValue()); + } + break; + case Notification.ADD: + if (msg.getNewValue() != null) { + attach((PAnnotatedEModelElement) msg.getNewValue()); + } + break; + case Notification.ADD_MANY: + attach((List<? extends Object>) msg.getNewValue()); + break; + case Notification.REMOVE: + if (msg.getOldValue() != null) { + detach((PAnnotatedEModelElement) msg.getOldValue()); + } + break; + case Notification.REMOVE_MANY: + detach((List<? extends Object>) msg.getNewValue()); + break; + } + } + } + super.notifyChanged(msg); + } + }; + + final MapTrackingAdapter itsMapTrackingAdapter; + + /** + * The cached value of the '{@link #getPaEPackages() <em>Pa EPackages</em>}' containment reference list. + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @see #getPaEPackages() + * @generated + * @ordered + */ + protected EList<PAnnotatedEPackage> paEPackages; + + /** + * Record the association between the EModelElement and the + * PAnnotatedEModelElement that are contained in this PAnnotatedModel + * content. + */ + protected final Map<EModelElement, PAnnotatedEModelElement> eElement_to_pElement; + + /** Set to true if initialized */ + private boolean initialized = false; + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * + * @generated NOT + */ + protected PAnnotatedModelImpl() { + eElement_to_pElement = new HashMap<EModelElement, PAnnotatedEModelElement>(); + itsMapTrackingAdapter = new MapTrackingAdapter(); + this.eAdapters().add(itsMapTrackingAdapter); + } + + /** Return the mapping from epackage elements to annotated package elements */ + public Map<EModelElement, PAnnotatedEModelElement> getModelElementMapping() { + return eElement_to_pElement; + } + + /** Merge the passed annotated model in this one */ + public void merge(PAnnotatedModel pModel) { + eElement_to_pElement.putAll(pModel.getModelElementMapping()); + } + + /** + * Register the association among a PAnnotatedEModelElement and its + * annotated EModelElement. If another PAnnotatedEModelElement was + * associatied to the same EModelElement, such association will be broken. + * + * <p> + * In order to mantain the consistency of the model, whenever an association + * among a PAnnotatedEModelElement <code>pa</code> and an EModelElement + * <code>e</code> is broken, the annotatedElement feature of <code>pa</code> + * is unset. + */ + protected void addMapping(PAnnotatedEModelElement target) { + final EModelElement eModelElement = target.getModelElement(); + if (eModelElement != null) { + PAnnotatedEModelElement prevAssoc = eElement_to_pElement + .get(eModelElement); + if (prevAssoc != null) { + removeMapping(eModelElement); + prevAssoc.setModelElement(null); + } + eElement_to_pElement.put(eModelElement, target); + } + } + + /** + * Unregister the association between an <code>EModelElement</code> and the + * <code>PAnnotatedEModelElement</code> that references it via the + * <code>annotatedElement</code> feature. + */ + protected void removeMapping(EModelElement eModelElement) { + final Object prevAssoc = eElement_to_pElement.remove(eModelElement); + assert prevAssoc != null; + } + + /** + * Invoked whenever a new PAnnotatedEModelElement is added to the + * PAnnotatedModel. + */ + protected void attach(PAnnotatedEModelElement aElement) { + aElement.eAdapters().add(0, itsMapTrackingAdapter); + addMapping(aElement); + attach(aElement.eContents()); + } + + /** + * Invoked whenever a set of new PAnnotatedEModelElement is added to the + * PAnnotatedModel. + */ + protected void attach(List<? extends Object> aElements) { + for (Object x : aElements) { + if (x instanceof PAnnotatedEModelElement) { + attach((PAnnotatedEModelElement) x); + } + } + } + + /** + * Invoked whenever a PAnnotatedEModelElement is removed from the + * PAnnotatedModel. + */ + protected void detach(PAnnotatedEModelElement aElement) { + aElement.eAdapters().remove(itsMapTrackingAdapter); + ENamedElement annotatedElement = aElement.getModelElement(); + if (annotatedElement != null) { + removeMapping(annotatedElement); + } + detach(aElement.eContents()); + } + + /** + * Invoked whenever a set of PAnnotatedEModelElement is removed from the + * PAnnotatedModel. + */ + protected void detach(List<? extends Object> aElements) { + for (Object x : aElements) { + if (x instanceof PAnnotatedEModelElement) { + detach((PAnnotatedEModelElement) x); + } + } + } + + /** + * Invariant: the eElement_to_pElement map agree with the PAnnotatedModel + * content. + * <p> + * This method should be used only for debugging. TODO use in validation. + */ + public void invMapIsWellFormed() { + Set<EModelElement> definedUnused = new HashSet<EModelElement>( + eElement_to_pElement.keySet()); + for (TreeIterator<? extends Object> i = EcoreUtil + .getAllContents(eContents()); i.hasNext();) { + Object x = i.next(); + if (x instanceof PAnnotatedEModelElement) { + PAnnotatedEModelElement paElement = (PAnnotatedEModelElement) x; + ENamedElement annotatedElement = paElement.getModelElement(); + if (annotatedElement != null) { + assert getPAnnotated(annotatedElement) == paElement; + definedUnused.remove(annotatedElement); + } + } else { + i.prune(); + } + } + assert definedUnused.isEmpty(); + } + + /** + * @return Returns the unique <code>PAnnotatedEModelElement</code> + * associated (via the <code>annotatedElement</code> feature) to the + * given <code>EModelElement</code>. + */ + public PAnnotatedEModelElement getPAnnotated(EModelElement e) { + checkAnnotatedPresent(e, eElement_to_pElement); + return eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEPackage</code> associated + * (via the <code>annotatedElement</code> feature) to the given + * <code>EPackage</code>. + */ + public PAnnotatedEPackage getPAnnotated(EPackage e) { + checkAnnotatedPresent(e, eElement_to_pElement); + return (PAnnotatedEPackage) eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEClass</code> associated (via + * the <code>annotatedElement</code> feature) to the given + * <code>EClass</code>. + */ + public PAnnotatedEClass getPAnnotated(EClass e) { + // in this case do not throw an error + if (e.getEPackage() instanceof EcorePackage) { + return (PAnnotatedEClass) eElement_to_pElement.get(e); + } + checkAnnotatedPresent(e, eElement_to_pElement); + return (PAnnotatedEClass) eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEStructuralFeature</code> + * associated (via the <code>annotatedElement</code> feature) to the + * given <code>EStructuralFeature</code>. + */ + public PAnnotatedEStructuralFeature getPAnnotated(EStructuralFeature e) { + checkAnnotatedPresent(e, eElement_to_pElement); + return (PAnnotatedEStructuralFeature) eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEDataType</code> associated + * (via the <code>annotatedElement</code> feature) to the given + * <code>EDataType</code>. + */ + public PAnnotatedEDataType getPAnnotated(EDataType e) { + // do not check because many datatypes belong to the emf package + return (PAnnotatedEDataType) eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEAttribute</code> associated + * (via the <code>annotatedElement</code> feature) to the given + * <code>EAttribute</code>. + */ + public PAnnotatedEAttribute getPAnnotated(EAttribute e) { + checkAnnotatedPresent(e, eElement_to_pElement); + return (PAnnotatedEAttribute) eElement_to_pElement.get(e); + } + + /** + * @return Returns the unique <code>PAnnotatedEReference</code> associated + * (via the <code>annotatedElement</code> feature) to the given + * <code>EReference</code>. + */ + public PAnnotatedEReference getPAnnotated(EReference e) { + checkAnnotatedPresent(e, eElement_to_pElement); + return (PAnnotatedEReference) eElement_to_pElement.get(e); + } + + /** + * Checks if there is a annotated model element for the passed emf model + * element. If not then an illegal argument is thrown + */ + private void checkAnnotatedPresent(EModelElement ee, + Map<EModelElement, PAnnotatedEModelElement> map) { + if (!isInitialized()) { + return; // at this point the model is not yet fully initialized. + } + if (ee == null) { + throw new IllegalArgumentException( + "Trying to retrieve Annotated Type using null. " + + "This can occur if not all epackages have been registered with Teneo.\n" + + "Or this can occur if epackages which refer to eachother are placed in different ecore/xsd files " + + "and they are not read using one resource set. The reference from one epackage to another must be " + + "resolvable by EMF."); + } + if (map.get(ee) == null) { + final String name = ee instanceof ENamedElement ? " for: " + + ((ENamedElement) ee).getName() : ""; + throw new IllegalArgumentException( + "No annotated model element present " + name + " for type " + + ee.eClass().getName() + + " has its epackage been registered with Teneo?"); + } + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + @Override + protected EClass eStaticClass() { + return PamodelPackage.Literals.PANNOTATED_MODEL; + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + public EList<PAnnotatedEPackage> getPaEPackages() { + if (paEPackages == null) { + paEPackages = new EObjectContainmentWithInverseEList<PAnnotatedEPackage>(PAnnotatedEPackage.class, this, PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES, PamodelPackage.PANNOTATED_EPACKAGE__PA_MODEL); + } + return paEPackages; + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + @SuppressWarnings("unchecked") + @Override + public NotificationChain eInverseAdd(InternalEObject otherEnd, + int featureID, NotificationChain msgs) { + switch (featureID) { + case PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + return ((InternalEList<InternalEObject>)(InternalEList<?>)getPaEPackages()).basicAdd(otherEnd, msgs); + } + return super.eInverseAdd(otherEnd, featureID, msgs); + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + @Override + public NotificationChain eInverseRemove(InternalEObject otherEnd, + int featureID, NotificationChain msgs) { + switch (featureID) { + case PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + return ((InternalEList<?>)getPaEPackages()).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 PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + return getPaEPackages(); + } + 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 PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + getPaEPackages().clear(); + getPaEPackages().addAll((Collection<? extends PAnnotatedEPackage>)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + @Override + public void eUnset(int featureID) { + switch (featureID) { + case PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + getPaEPackages().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * <!-- begin-user-doc --> <!-- end-user-doc --> + * @generated + */ + @Override + public boolean eIsSet(int featureID) { + switch (featureID) { + case PamodelPackage.PANNOTATED_MODEL__PA_EPACKAGES: + return paEPackages != null && !paEPackages.isEmpty(); + } + return super.eIsSet(featureID); + } + + /** + * Returns a sequence generator on the basis of its name, if not found then + * an exception is thrown. efeature is passed for debugging purposes. + */ + public SequenceGenerator getSequenceGenerator(EStructuralFeature efeature, + String name) { + // TODO: should not only the paepackage of the efeature be checked? + for (PAnnotatedEPackage pae : getPaEPackages()) { + for (SequenceGenerator sg : pae.getSequenceGenerators()) { + if (sg.getName() != null && sg.getName().compareTo(name) == 0) { + return sg; + } + } + for (PAnnotatedEClass aClass : pae.getPaEClasses()) { + for (SequenceGenerator sg : aClass.getSequenceGenerators()) { + if (sg.getName() != null && sg.getName().compareTo(name) == 0) { + return sg; + } + } + + for (PAnnotatedEStructuralFeature aFeature : aClass + .getPaEStructuralFeatures()) { + if (aFeature.getSequenceGenerator() != null && + aFeature.getSequenceGenerator().getName() != null + && aFeature.getSequenceGenerator().getName() + .compareTo(name) == 0) { + return aFeature.getSequenceGenerator(); + } + } + } + } + throw new IllegalStateException( + "No sequence generator found with the name: " + name + + ", name is used in " + "annotation of element " + + efeature.getEContainingClass().getName() + "/" + + efeature.getName()); + } + + public SequenceStyleGenerator getSequenceStyleGenerator( + EStructuralFeature efeature, String name) { + // TODO: should not only the paepackage of the efeature be checked? + for (PAnnotatedEPackage pae : getPaEPackages()) { + for (SequenceStyleGenerator sg : pae.getSequenceStyleGenerators()) { + if (sg.getName() != null && sg.getName().compareTo(name) == 0) { + return sg; + } + } + } + throw new IllegalStateException( + "No sequence generator found with the name: " + name + + ", name is used in " + "annotation of element " + + efeature.getEContainingClass().getName() + "/" + + efeature.getName()); + } + + /** + * Returns a table generator on the basis of its name, if not found then an + * exception is thrown. efeature is passed for debugging purposes. + */ + public TableGenerator getTableGenerator(EStructuralFeature efeature, + String name) { + // TODO: should not only the paepackage of the efeature be checked? + for (PAnnotatedEPackage pae : getPaEPackages()) { + for (TableGenerator tg : pae.getTableGenerators()) { + if (tg.getName() != null && tg.getName().compareTo(name) == 0) { + return tg; + } + } + for (PAnnotatedEClass pec : pae.getPaEClasses()) { + if (pec.getTableGenerator() != null + && pec.getTableGenerator().getName() != null + && pec.getTableGenerator().getName().compareTo(name) == 0) { + return pec.getTableGenerator(); + } + + for (PAnnotatedEStructuralFeature pef : pec + .getPaEStructuralFeatures()) { + for (TableGenerator tg : pef.getTableGenerators()) { + if (tg.getName() != null + && tg.getName().compareTo(name) == 0) { + return tg; + } + } + } + } + } + + return null; + } + + /** + * @return the initialized + */ + public boolean isInitialized() { + return initialized; + } + + /** + * @param initialized + * the initialized to set + */ + public void setInitialized(boolean initialized) { + this.initialized = initialized; + } + + private ConcurrentHashMap<String, EClass> entityNameToEClass = new ConcurrentHashMap<String, EClass>(); + + /** + * @return the eclass annotated with this entity name. If not found then an + * exception is thrown + */ + public EClass getEClass(String entityName) { + EClass eClass; + if ((eClass = entityNameToEClass.get(entityName)) != null) { + return eClass; + } + for (PAnnotatedEPackage aPackage : getPaEPackages()) { + for (PAnnotatedEClass aClass : aPackage.getPaEClasses()) { + if (aClass.getEntity() != null + && aClass.getEntity().getName() != null + && aClass.getEntity().getName().compareTo(entityName) == 0) { + entityNameToEClass.put(entityName, aClass.getModelEClass()); + return aClass.getModelEClass(); + } + } + } + throw new IllegalArgumentException( + "No Annotated EClass for entityName " + entityName); + } + + /** + * @return the EClassifier for a certain name. First the eclasses are + * searched using the name as the entityname then the edatatypes are + * searched. + */ + public EClassifier getEClassifier(String name) { + if (hasEClass(name)) { + return getEClass(name); + } + + for (PAnnotatedEPackage aPackage : getPaEPackages()) { + final EClassifier eClassifier = aPackage.getModelEPackage() + .getEClassifier(name); + if (eClassifier instanceof EDataType) { + return eClassifier; + } + } + throw new IllegalArgumentException("No EClassifier for name " + name); + } + + /** + * @return true if there is an EClass with the name as entityname or an + * EDataType with the name passed as a parameter. + */ + public boolean hasEClassifier(String name) { + if (hasEClass(name)) { + return true; + } + + for (PAnnotatedEPackage aPackage : getPaEPackages()) { + final EClassifier eClassifier = aPackage.getModelEPackage() + .getEClassifier(name); + if (eClassifier instanceof EDataType) { + return true; + } + } + return false; + } + + /** @return true if there is annotated eclass with the passed entityname */ + public boolean hasEClass(String entityName) { + if (entityNameToEClass.get(entityName) != null) { + return true; + } + for (PAnnotatedEPackage aPackage : getPaEPackages()) { + for (PAnnotatedEClass aClass : aPackage.getPaEClasses()) { + if (aClass.getEntity() != null + && aClass.getEntity().getName() != null + && aClass.getEntity().getName().compareTo(entityName) == 0) { + entityNameToEClass.put(entityName, aClass.getModelEClass()); + return true; + } + } + } + return false; + } + + /** Dump this model to xml */ + public String toXML() { + try { + final XMLResourceImpl xmlResource = new XMLResourceImpl(); + xmlResource.getContents().add(this); + final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + final HashMap<String, String> options = new HashMap<String, String>(); + options.put(XMLResource.OPTION_PROCESS_DANGLING_HREF, + XMLResource.OPTION_PROCESS_DANGLING_HREF_RECORD); + xmlResource.save(bos, options); + final String res = bos.toString(); + bos.close(); + return res; + } catch (IOException e) { + // todo replace with teneo exception + throw new IllegalStateException( + "Exception while converting pamodel to a xml string", e); + } + } + +} // PAnnotatedModelImpl |