/**
* <copyright>
*
* Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others
* 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:
* Martin Taal
* Davide Marchignoli
* </copyright>
*
* $Id: BasicPamodelBuilder.java,v 1.4 2008/02/28 07:08:32 mtaal Exp $
*/
package org.eclipse.emf.teneo.annotations.mapper;
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.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
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.PAnnotatedEStructuralFeature;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel;
import org.eclipse.emf.teneo.annotations.pamodel.PamodelFactory;
import org.eclipse.emf.teneo.extension.ExtensionPoint;
/**
* Convience class for building a <code>PAnnotatedModel</code>.
*
* @author <a href="mailto:marchign at elver.org">Davide Marchignoli</a>
*/
public class BasicPamodelBuilder implements ExtensionPoint {
private PAnnotatedModel target = null;
/**
* Uses an empty freshly instantiated PAnnotatedModel as target.
*/
public BasicPamodelBuilder() {
setPAnnotatedModel(createPAnnotatedModel());
}
/** Create the pAnnotatedModel */
public PAnnotatedModel createPAnnotatedModel() {
return PamodelFactory.eINSTANCE.createPAnnotatedModel();
}
/**
* Uses the given PAnnotatedMmodel as target.
*/
public BasicPamodelBuilder(PAnnotatedModel target) {
setPAnnotatedModel(target);
}
/**
* Sets the target PAnnotatedModel
*/
public void setPAnnotatedModel(PAnnotatedModel target) {
this.target = target;
}
/**
* @return the target model.
*/
public PAnnotatedModel getPAnnotatedModel() {
return target;
}
/**
* @return a <code>PAnnotatedModelElement</code> assoiciated to the given
* <code>EModelElement</code>. The element is created only if not already present in
* the model.
*/
protected PAnnotatedEModelElement create(EModelElement eModelElement) {
PAnnotatedEModelElement paElement = target.getPAnnotated(eModelElement);
if (paElement == null) {
// Factor out actual model creation so that extensions can create their
// own model elements.
paElement = doCreate(eModelElement);
}
return paElement;
}
/**
* @return A newly created PAnnotatedEModelElement. This method is only responsible for the
* actual creation (and initialization) of this object. No other logic should happen
* here. This allows subclasses to alter how objects are created. If you'd like to alter
* any other logic around the creation, you should override the <code>create</code>
* method(s).
* @throws AssertionError
*/
protected PAnnotatedEModelElement doCreate(EModelElement eModelElement) throws AssertionError {
final EClass eModelElementEClass = eModelElement.eClass();
PAnnotatedEModelElement paElement;
switch (eModelElementEClass.getClassifierID()) {
case EcorePackage.EATTRIBUTE:
paElement = PamodelFactory.eINSTANCE.createPAnnotatedEAttribute();
break;
case EcorePackage.EREFERENCE:
paElement = PamodelFactory.eINSTANCE.createPAnnotatedEReference();
break;
case EcorePackage.ECLASS:
paElement = PamodelFactory.eINSTANCE.createPAnnotatedEClass();
break;
case EcorePackage.EPACKAGE:
paElement = PamodelFactory.eINSTANCE.createPAnnotatedEPackage();
break;
case EcorePackage.EENUM:
case EcorePackage.EDATA_TYPE:
paElement = PamodelFactory.eINSTANCE.createPAnnotatedEDataType();
break;
default:
throw new AssertionError("Trying to build PAnnotatedEModelElement for a " + eModelElementEClass);
}
paElement.setModelElement((ENamedElement) eModelElement);
return paElement;
}
/**
* @return a <code>PAnnotatedEPackage</code> associated to the given <code>EPackage</code>
* and adds it the model.
* <p>
* The <code>PAnnotatedEPackage</code> is created only if not already present in the
* model.
*/
protected PAnnotatedEPackage pElement(EPackage ePackage) {
PAnnotatedEPackage pPackage = (PAnnotatedEPackage) create(ePackage);
if (pPackage.eContainer() == null) {
target.getPaEPackages().add(pPackage);
}
return pPackage;
}
/**
* @return a <code>PAnnotatedEClass</code> associated to the given <code>EClass</code> and
* adds it the model.
* <p>
* The <code>PAnnotatedEClass</code> is created only if not already present in the
* model.
* <p>
* The operation may involve the creation of a <code>PAnnotatedEPackage</code>
* associated to the given <code>EClass</code> package.
*/
protected PAnnotatedEClass pElement(EClass eClass) {
PAnnotatedEClass pClass = (PAnnotatedEClass) create(eClass);
pElement(eClass.getEPackage()).getPaEClasses().add(pClass);
return pClass;
}
/**
* @return a <code>PAnnotatedEStructuralFeature</code> associated to the given
* <code>EStructuralFeature</code> and adds it the model.
* <p>
* The <code>PAnnotatedEStructuralFeature</code> is created only if not already
* present in the model.
* <p>
* The operation may involve the creation of a <code>PAnnotatedEPackage</code> and a
* <code>PAnnotatedEClass</code>.
*/
protected PAnnotatedEModelElement pElement(EStructuralFeature eFeature) {
PAnnotatedEStructuralFeature pFeature = (PAnnotatedEStructuralFeature) create(eFeature);
pElement(eFeature.getEContainingClass()).getPaEStructuralFeatures().add(pFeature);
return pFeature;
}
/**
* @return a <code>PAnnotatedEStructuralFeature</code> associated to the given
* <code>EStructuralFeature</code> and adds it the model.
* <p>
* The <code>PAnnotatedEStructuralFeature</code> is created only if not already
* present in the model.
* <p>
* The operation may involve the creation of a <code>PAnnotatedEPackage</code> and a
* <code>PAnnotatedEClass</code>.
*/
protected PAnnotatedEDataType pElement(EDataType eDataType) {
PAnnotatedEDataType pDataType = (PAnnotatedEDataType) create(eDataType);
pElement(eDataType.getEPackage()).getPaEDataTypes().add(pDataType);
return pDataType;
}
/**
* @return a <code>PAnnotatedEModelElement</code> associated to the given
* <code>EModelElement</code> and adds it the model.
* @see #pElement(EPackage)
* @see #pElement(EClass)
* @see #pElement(EStructuralFeature)
*/
protected PAnnotatedEModelElement pElement(final EModelElement eElement) throws AssertionError {
PAnnotatedEModelElement pElement = null;
switch (eElement.eClass().getClassifierID()) {
case EcorePackage.EATTRIBUTE:
case EcorePackage.EREFERENCE:
pElement = pElement((EStructuralFeature) eElement);
break;
case EcorePackage.ECLASS:
pElement = pElement((EClass) eElement);
break;
case EcorePackage.EPACKAGE:
pElement = pElement((EPackage) eElement);
break;
case EcorePackage.EDATA_TYPE:
pElement = pElement((EDataType) eElement);
break;
default:
throw new AssertionError("Trying to build PAnnotatedEModelElement for a " + eElement.eClass());
}
return pElement;
}
/**
* Builds a <code>PAnnotatedEPackage</code> associated to the given <code>EPackage</code>
* (if such an <code>PAnnotatedEPackage</code> does not yet exists) and adds it to the target
* model.
*/
public void add(EPackage ePackage) {
pElement(ePackage);
}
/**
* Builds a <code>PAnnotatedEClass</code> associated to the given <code>EClass</code> (if
* such an <code>PAnnotatedEClass</code> does not yet exists) and adds it to the target model.
*
* <p>
* The creation of a new <code>PAnnotatedEClass</code> may involve the creation of a
* <code>PAnnotatedEPackage</code> associated to the containing <code>EPackage</code> of the
* given class.
*/
public void add(EClass eClass) {
pElement(eClass);
}
/**
* Add to the the target model a new <code>PAnnotatedEStructuralFeature</code> refering to the
* given EStructuralFeature.
*
* <p>
* A PAnnotatedEClass and a PAnnotatedEPackage for the containing EClass and EPackage are added
* if needed.
*
* <p>
* The added element have no annotations. Elements for which a corresponding PAnnotatedElement
* is already present in the target model are ignored.
*/
public void add(EStructuralFeature eFeature) {
pElement(eFeature);
}
/**
* Add the given annotation to the given PAnnotatedEModelElement.
*
* @throws IllegalArgumentException
* if the given PAnnotation is not admitted for the given PAnnotatedEModelElement.
* protected void setPAnnotation(PAnnotatedEModelElement pElement, PAnnotation
* pAnnotation) { EReference pAnnotationRef =
* PamodelPackage.eINSTANCE.pAnnotationReference(pElement.eClass(),
* pAnnotation.eClass()); if (pAnnotationRef == null) throw new
* IllegalArgumentException("PAnnotation of type '" + pAnnotation.eClass() + "' does
* not apply to elements of type '" + pElement.eClass() + "'");
* pElement.eSet(pAnnotationRef, pAnnotation); }
*/
/**
* Add the given PAnnotation to the target model.
*
* <p>
* This operation may involve the addition to the model of a newly created
* PAnnotatedEModelElement for the PAnnotation EModelElement.
*
* @throws NullPointerException
* if either <code>pAnnotation</code> or
* <code>pAnnotation.getEModelElement()</code> are null.
* @throws IllegalArgumentException
* if the given <code>PAnnotation</code> references an invalid
* <code>PAnnotatedElement</code> public void add(PAnnotation pAnnotation) {
* PAnnotatedEModelElement pElement = pElement(pAnnotation.getEModelElement());
* setPAnnotation(pElement, pAnnotation); }
*/
/**
* Add to the the target model a new PAnnotatedPackage refering to the given EPackage.
* Recursively adds a PAnnotatedEClass for each EClass in the given EPackage (see
* {@link addEClass}).
*
* <p>
* The added elements have no annotations. Elements for which a corresponding PAnnotatedElement
* is already present in the target model are ignored.
*/
public void addRecurse(EPackage ePackage) {
PAnnotatedEPackage paPackage = pElement(ePackage);
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
if (eClassifier instanceof EClass) {
addRecurse(paPackage, (EClass) eClassifier);
} else if (eClassifier instanceof EDataType) {
pElement((EDataType) eClassifier);
}
}
}
/**
* used by {@link #addRecurse(EPackage)} to avoid recomputing the container multiple times.
*/
protected void addRecurse(PAnnotatedEPackage paPackage, EClass eClass) {
PAnnotatedEClass paClass = (PAnnotatedEClass) create(eClass);
if (paClass.eContainer() == null) {
paPackage.getPaEClasses().add(paClass);
}
for (EStructuralFeature eStructuralFeature : eClass.getEStructuralFeatures()) {
add(paClass, eStructuralFeature);
}
}
/**
* Add to the the target model a new PAnnotatedPackage refering to the given EClass. Recursively
* adds a PAnnotatedEStructuralFeature for each EStructuralFeature in the given EClass (see
* {@link addEStructuralFeature}).
*
* <p>
* A PAnnotatedEPackage for the containng EPackage is added if needed.
*
* <p>
* The added elements have no annotations.
*
* <p>
* Elements for which a corresponding PAnnotatedElement is already present in the target model
* are ignored. public void addRecurse(EClass eClass) { addRecurse((PAnnotatedEPackage)
* pElement(eClass), eClass); }
*/
/**
* used by {@link #addRecurse(EClass)} to avoid recomputing the container multiple times.
*/
protected void add(PAnnotatedEClass paClass, EStructuralFeature eFeature) {
PAnnotatedEStructuralFeature paFeature = (PAnnotatedEStructuralFeature) create(eFeature);
if (paFeature.eContainer() == null) {
paClass.getPaEStructuralFeatures().add(paFeature);
}
}
}