blob: 5af00749188a9c614b9aae022b9ce41a98281b42 [file] [log] [blame]
/*
* Copyright (c) 2008, 2009 Borland Software Corporation
*
* 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:
* Artem Tikhomirov (Borland) - initial API and implementation
*/
package org.eclipse.gmf.internal.codegen.util;
import java.util.HashMap;
import java.util.List;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.internal.common.migrate.FilteringCopier;
/**
* Migrate GMFGen model from year 2006-2007 (as of 2.0 release) to version of
* year 2008 (release 2.1)
* @author artem
*/
public /*package-local, but need to be visible from tests*/ class Migrate2008 {
private boolean myIsMigrationApplied = false;
private final EPackage myMetaPackage;
public Migrate2008() {
//myMetaPackage = GMFGenPackage.eINSTANCE;
myMetaPackage = EPackage.Registry.INSTANCE.getEPackage(ModelVersions.GMFGEN_2_1);
}
@SuppressWarnings("unchecked")
public EObject go(EObject o) {
EPackage oldGenModel = o.eClass().getEPackage();
final EStructuralFeature modelElementSelector = ((EClass) oldGenModel.getEClassifier("TypeModelFacet")).getEStructuralFeature("modelElementSelector");
final EStructuralFeature valueExprLanguage = ((EClass) oldGenModel.getEClassifier("ValueExpression")).getEStructuralFeature("language");
final EStructuralFeature gfvsBody = ((EClass) oldGenModel.getEClassifier("GenFeatureValueSpec")).getEStructuralFeature("body");
final EStructuralFeature lcSourceEnd = ((EClass) oldGenModel.getEClassifier("GenLinkConstraints")).getEStructuralFeature("sourceEnd");
final EStructuralFeature lcTargetEnd = ((EClass) oldGenModel.getEClassifier("GenLinkConstraints")).getEStructuralFeature("targetEnd");
final EStructuralFeature auditRule = ((EClass) oldGenModel.getEClassifier("GenAuditRule")).getEStructuralFeature("rule");
final EStructuralFeature metricRule = ((EClass) oldGenModel.getEClassifier("GenMetricRule")).getEStructuralFeature("rule");
final EStructuralFeature providers = ((EClass) oldGenModel.getEClassifier("GenExpressionProviderContainer")).getEStructuralFeature("providers");
final EStructuralFeature ctxSelectorClassName = ((EClass) oldGenModel.getEClassifier("GenAuditRule")).getEStructuralFeature("contextSelectorLocalClassName");
//
FilteringCopier cc = new FilteringCopier(myMetaPackage);
cc.ignore(modelElementSelector);
cc.ignore(valueExprLanguage);
cc.ignore(gfvsBody);
cc.ignore(lcSourceEnd);
cc.ignore(lcTargetEnd);
cc.ignore(auditRule);
cc.ignore(metricRule);
cc.ignore(providers);
cc.ignore(ctxSelectorClassName);
EObject result = cc.go(o);
//
HashMap<EObject, EObject> oldValueExpr2New = new HashMap<EObject, EObject>();
assert cc.getIgnoredOwners(providers).size() < 2;
EObject providerContainer = cc.getIgnoredOwners(providers).isEmpty() ? null : cc.getIgnoredOwners(providers).get(0);
if (providerContainer != null) {
EObject newProviderContainer = cc.get(providerContainer);
List<EObject> allNewProviders = (List<EObject>) newProviderContainer.eGet(newProviderContainer.eClass().getEStructuralFeature(providers.getName()));
for (EObject oldProvider : (List<EObject>) providerContainer.eGet(providers)) {
EClass newProviderClass = (EClass) myMetaPackage.getEClassifier(oldProvider.eClass().getName());
EObject newProvider = myMetaPackage.getEFactoryInstance().create(newProviderClass);
if ("GenExpressionInterpreter".equals(oldProvider.eClass().getName())) {
EStructuralFeature oldLang = oldProvider.eClass().getEStructuralFeature("language");
EStructuralFeature oldClassName = oldProvider.eClass().getEStructuralFeature("className");
newProvider.eSet(newProviderClass.getEStructuralFeature(oldLang.getName()), cc.transformValue((EAttribute) oldLang, oldProvider.eGet(oldLang)));
newProvider.eSet(newProviderClass.getEStructuralFeature(oldClassName.getName()), oldProvider.eGet(oldClassName));
}
allNewProviders.add(newProvider);
EStructuralFeature provBaseExpressions = ((EClass) oldGenModel.getEClassifier("GenExpressionProviderBase")).getEStructuralFeature("expressions");
List<EObject> newProviderExpressions = (List<EObject>) newProvider.eGet(newProvider.eClass().getEStructuralFeature(provBaseExpressions.getName()));
for (EObject oldVE : (List<EObject>) oldProvider.eGet(provBaseExpressions)) {
EObject newVE;
if (oldVE.eClass().getName().equals("GenConstraint")) {
newVE = myMetaPackage.getEFactoryInstance().create((EClass) myMetaPackage.getEClassifier("GenConstraint"));
} else {
// intentionally transform GenFeatureValueSpec into plain ValueExpression
newVE = myMetaPackage.getEFactoryInstance().create((EClass) myMetaPackage.getEClassifier("ValueExpression"));
}
Object bodyValue = oldVE.eGet(oldVE.eClass().getEStructuralFeature("body"));
newVE.eSet(newVE.eClass().getEStructuralFeature("body"), bodyValue);
oldValueExpr2New.put(oldVE, newVE);
newProviderExpressions.add(newVE);
}
}
containment2AssociationCase(cc, modelElementSelector, oldValueExpr2New, allNewProviders);
containment2AssociationCase(cc, lcSourceEnd, oldValueExpr2New, allNewProviders);
containment2AssociationCase(cc, lcTargetEnd, oldValueExpr2New, allNewProviders);
containment2AssociationCase(cc, auditRule, oldValueExpr2New, allNewProviders);
containment2AssociationCase(cc, metricRule, oldValueExpr2New, allNewProviders);
for (EObject vs : cc.getIgnoredOwners(gfvsBody)) {
assert vs.eClass().getName().equals("GenFeatureValueSpec");
myIsMigrationApplied = true;
EObject newVS = cc.get(vs);
EObject newVE = oldValueExpr2New.get(vs);
if (newVE == null) {
// isCopy == true, need to match by lang/body
newVE = matchCopyVE(vs, allNewProviders);
}
if (newVE != null) {
newVS.eSet(newVS.eClass().getEStructuralFeature("value"), newVE);
}
}
}
for (EObject oldRule : cc.getIgnoredOwners(ctxSelectorClassName)) {
assert "GenAuditRule".equals(oldRule.eClass().getName());
if (!oldRule.eIsSet(ctxSelectorClassName)) {
continue;
}
EObject root = cc.get(oldRule.eGet(oldRule.eClass().getEStructuralFeature("root")));
assert root != null;
myIsMigrationApplied = true;
String className = (String) oldRule.eGet(ctxSelectorClassName);
EObject context = getOrCreateContext(root, className);
EObject target = cc.get(oldRule.eGet(oldRule.eClass().getEStructuralFeature("target")));
if (target != null) {
target.eSet(((EClass) myMetaPackage.getEClassifier("GenAuditable")).getEStructuralFeature("contextSelector"), context);
}
}
return result;
}
@SuppressWarnings("unchecked")
private static EObject matchCopyVE(EObject oldVE, List<EObject> allProviders) {
final EStructuralFeature langFeature = oldVE.eClass().getEStructuralFeature("language");
final EStructuralFeature bodyFeature = oldVE.eClass().getEStructuralFeature("body");
if (langFeature == null || bodyFeature == null) {
return null;
}
final Object langValue = oldVE.eClass().getEPackage().getEFactoryInstance().convertToString((EDataType) langFeature.getEType(), oldVE.eGet(langFeature));
final Object bodyValue = oldVE.eGet(bodyFeature);
if (bodyValue != null) {
for (EObject p : allProviders) {
EStructuralFeature provLangFeat = p.eClass().getEStructuralFeature("language");
// java provider has no language feature, hence hardcoded "java" value
Object providerLang = provLangFeat == null ? "java" : p.eClass().getEPackage().getEFactoryInstance().convertToString((EDataType) provLangFeat.getEType(), p.eGet(provLangFeat));
if (providerLang != null && providerLang.equals(langValue)) {
for (EObject ve : (List<EObject>) p.eGet(p.eClass().getEStructuralFeature("expressions"))) {
EStructuralFeature veBodyFeature = ve.eClass().getEStructuralFeature("body");
if (veBodyFeature != null /* just in case */&& bodyValue.equals(ve.eGet(veBodyFeature))) {
return ve;
}
}
}
}
} // body == null, no much sense to match...
return null;
}
private void containment2AssociationCase(FilteringCopier cc, EStructuralFeature oldFeature, HashMap<EObject, EObject> old2newVE, List<EObject> allProviders) {
for (EObject o : cc.getIgnoredOwners(oldFeature)) {
EObject n = cc.get(o);
Object oldVE = o.eGet(oldFeature);
if (oldVE == null) {
continue; //nothing to do.
}
myIsMigrationApplied = true;
EObject newVE = old2newVE.get(oldVE);
if (newVE == null) {
// isCopy == true, need to match by lang/body
if (oldVE instanceof EObject) {
newVE = matchCopyVE((EObject) oldVE, allProviders);
}
}
if (newVE != null) {
n.eSet(n.eClass().getEStructuralFeature(oldFeature.getName()), newVE);
}
}
}
@SuppressWarnings("unchecked")
private static EObject getOrCreateContext(EObject root, String className) {
assert root != null && "GenAuditRoot".equals(root.eClass().getName());
EPackage metaPackage = root.eClass().getEPackage();
EClass class_genAuditContext = (EClass) metaPackage.getEClassifier("GenAuditContext");
EStructuralFeature feature_genAuditContext_className = class_genAuditContext.getEStructuralFeature("className");
EStructuralFeature feature_genAuditContext_id = class_genAuditContext.getEStructuralFeature("id");
EStructuralFeature feature_genAuditRoot_clientContexts = root.eClass().getEStructuralFeature("clientContexts");
EObject context = null;
for (EObject next : (List<EObject>) root.eGet(feature_genAuditRoot_clientContexts)) {
String explicit = (String) next.eGet(feature_genAuditContext_className);
if (className == explicit || (className != null && className.equals(explicit)) || (explicit == null && className.equals(next.eGet(feature_genAuditContext_id)))) {
context = next;
break;
}
}
if (context == null) {
context = metaPackage.getEFactoryInstance().create(class_genAuditContext);
String id = generateUnique(root, className == null ? "" : className);
context.eSet(feature_genAuditContext_id, id);
if (!id.equals(className)) {
context.eSet(feature_genAuditContext_className, className);
}
((List<EObject>) root.eGet(feature_genAuditRoot_clientContexts)).add(context);
}
return context;
}
@SuppressWarnings("unchecked")
private static String generateUnique(EObject root, String defaultId) {
assert root != null && "GenAuditRoot".equals(root.eClass().getName());
String id = defaultId;
int i = 0;
boolean haveSuchId = false;
EStructuralFeature feature_genAuditRoot_clientContexts = root.eClass().getEStructuralFeature("clientContexts");
do {
haveSuchId = false;
for (EObject next : (List<EObject>) root.eGet(feature_genAuditRoot_clientContexts)) {
EStructuralFeature feature_genAuditContext_id = next.eClass().getEStructuralFeature("id");
if (id.equals(next.eGet(feature_genAuditContext_id))) {
haveSuchId = true;
id = defaultId + (++i);
break;
}
}
} while (haveSuchId);
return id;
}
public boolean wasMigrationApplied() {
return myIsMigrationApplied;
}
}