blob: a782625166da62be41981b435f25cd1b0459be1c [file] [log] [blame]
package org.eclipse.emf.edapt.declaration.replacement;
import java.util.ArrayList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edapt.declaration.EdaptConstraint;
import org.eclipse.emf.edapt.declaration.EdaptOperation;
import org.eclipse.emf.edapt.declaration.EdaptParameter;
import org.eclipse.emf.edapt.declaration.OperationImplementation;
import org.eclipse.emf.edapt.internal.common.MetamodelFactory;
import org.eclipse.emf.edapt.spi.migration.Instance;
import org.eclipse.emf.edapt.spi.migration.Metamodel;
import org.eclipse.emf.edapt.spi.migration.Model;
import org.eclipse.emf.edapt.spi.migration.ReferenceSlot;
/**
* {@description}
*
* @author herrmama
* @author $Author$
* @version $Rev$
* @levd.rating YELLOW Hash: D7F34E82CD011CB2D815D0AC50B31E10
*/
@EdaptOperation(identifier = "replaceInheritanceByDelegation", label = "Inheritance to Delegation", description = "In the metamodel, inheritance from a super class is replaced by delegation to this class. More specifically, the super class is removed and a containment reference to this class is created. In the model, the contents associated to the super class are extracted to a separate instance of the super class.")
public class ReplaceInheritanceByDelegation extends OperationImplementation {
/** {@description} */
@EdaptParameter(main = true, description = "The class from which the super class is removed")
public EClass subClass;
/** {@description} */
@EdaptParameter(description = "The super class to be removed")
public EClass superClass;
/** {@description} */
@EdaptConstraint(restricts = "superClass", description = "The super class must be a super type of the sub class")
public boolean checkSuperClass(EClass superClass) {
return subClass.getESuperTypes().contains(superClass);
}
/** {@description} */
@EdaptParameter(description = "The name of the reference to the super class")
public String referenceName;
/** {@inheritDoc} */
@Override
public void execute(Metamodel metamodel, Model model) {
// metamodel adaptation
subClass.getESuperTypes().remove(superClass);
final EReference delegation = MetamodelFactory.newEReference(subClass,
referenceName, superClass, 1, 1, true);
// model migration
for (final Instance instance : model.getAllInstances(subClass)) {
final Instance delegate = model.newInstance(superClass);
instance.set(delegation, delegate);
for (final EStructuralFeature feature : superClass
.getEAllStructuralFeatures()) {
delegate.set(feature, instance.unset(feature));
}
for (final ReferenceSlot slot : new ArrayList<ReferenceSlot>(instance
.getReferences())) {
final EReference reference = slot.getEReference();
final Instance source = slot.getInstance();
if (reference.getEReferenceType().isSuperTypeOf(superClass)) {
if (reference.isMany()) {
source.remove(reference, instance);
source.add(reference, delegate);
} else {
source.set(reference, delegate);
}
if (reference.isContainment()) {
instance.unset(delegation);
model.delete(instance);
}
}
}
}
}
}