blob: 475e2a975332790ddbdbeeef475d6eea2e27f846 [file] [log] [blame]
package org.eclipse.emf.edapt.declaration.inheritance;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
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.declaration.generalization.GeneralizeReference;
import org.eclipse.emf.edapt.migration.MigrationException;
import org.eclipse.emf.edapt.spi.migration.Metamodel;
import org.eclipse.emf.edapt.spi.migration.Model;
/**
* {@description}
*
* @author herrmama
* @author $Author$
* @version $Rev$
* @levd.rating YELLOW Hash: 294397E02180B9715AEEFB4A82A48B5A
*/
@EdaptOperation(identifier = "pullFeature", label = "Pull up Feature", description = "In the metamodel, a number of features are pulled up into a common super class. In the model, values are changed accordingly.", breaking = false)
public class PullFeature extends OperationImplementation {
/** {@description} */
@EdaptParameter(main = true, description = "The features to be pulled up")
public List<EStructuralFeature> features;
/** {@description} */
@EdaptParameter(description = "The super class to which the features are pulled")
public EClass targetClass;
/** {@description} */
@EdaptConstraint(restricts = "targetClass", description = "The features' classes must have a common super type")
public boolean checkTargetClassCommonSuperType(EClass targetClass) {
for (final EStructuralFeature feature : features) {
if (!feature.getEContainingClass().getESuperTypes()
.contains(targetClass)) {
return false;
}
}
return true;
}
/** {@description} */
@EdaptConstraint(description = "The features must not have opposite references")
public boolean checkReferencesOpposite() {
final EcorePackage mmm = EcorePackage.eINSTANCE;
if (features.size() > 1) {
return !isOfType(features, mmm.getEReference())
|| hasValue(features, mmm.getEReference_EOpposite(), null);
}
return true;
}
/** {@description} */
@EdaptConstraint(description = "The features have to be all containment references or not")
public boolean checkReferencesContainment() {
final EcorePackage mmm = EcorePackage.eINSTANCE;
return !isOfType(features, mmm.getEReference())
|| hasSameValue(features, mmm.getEReference_Containment());
}
/** {@description} */
@EdaptConstraint(description = "The features' multiplicities have to be the same")
public boolean checkFeaturesSameMultiplicity() {
final EcorePackage mmm = EcorePackage.eINSTANCE;
return hasSameValue(features, mmm.getETypedElement_LowerBound())
&& hasSameValue(features, mmm.getETypedElement_UpperBound());
}
/** {@description} */
@EdaptConstraint(description = "The features' types have to be the same")
public boolean checkFeaturesSameType() {
return hasSameValue(features,
EcorePackage.Literals.ETYPED_ELEMENT__ETYPE);
}
/** {@inheritDoc} */
@Override
public void initialize(Metamodel metamodel) {
if (targetClass == null) {
final List<EClass> superTypes = features.get(0).getEContainingClass()
.getESuperTypes();
if (!superTypes.isEmpty()) {
targetClass = superTypes.get(0);
}
}
}
/** {@inheritDoc} */
@SuppressWarnings("deprecation")
@Override
public void execute(Metamodel metamodel, Model model)
throws MigrationException {
final EStructuralFeature mainFeature = features.get(0);
targetClass.getEStructuralFeatures().add(mainFeature);
if (mainFeature instanceof EReference) {
final EReference mainReference = (EReference) mainFeature;
if (mainReference.getEOpposite() != null) {
final GeneralizeReference operation = new GeneralizeReference();
operation.reference = mainReference.getEOpposite();
operation.initialize(metamodel);
operation.type = targetClass;
operation.checkAndExecute(metamodel, model);
}
}
for (final EStructuralFeature feature : features) {
if (feature != mainFeature) {
final ReplaceFeature operation = new ReplaceFeature();
operation.toReplace = feature;
operation.replaceBy = mainFeature;
operation.checkAndExecute(metamodel, model);
}
}
}
}