/// <summary> /// Checks if all properties in k1 are found in k2. If yes, k2 is useless. /// </summary> /// <param name="k1"></param> /// <param name="k2"></param> /// <returns></returns> private static bool Subsumes(QVTRelations.IKey k1, QVTRelations.IKey k2) { if (k1.Part.Count <= k2.Part.Count && k1.PropertyPaths().Count <= k2.PropertyPaths().Count) { return(k1.Part.IsSubsetOf(k2.Part) && k1.PropertyPaths().All(k1PropertyPath => k2.PropertyPaths() .Any(k2PropertyPath => AreEqual(k1PropertyPath, k2PropertyPath)))); } return(false); }
private static void MergeKeyInto(QVTRelations.IKey existingKey, QVTRelations.IKey keyToBeMergedInto) { foreach (EMOF.IProperty propertyToMerge in keyToBeMergedInto.Part) { if (!existingKey.Part.Contains(propertyToMerge)) { existingKey.Part.Add(propertyToMerge); } } foreach (PropertyPath propertyPathToMerge in keyToBeMergedInto.PropertyPaths()) { if (existingKey.PropertyPaths().FirstOrDefault(pp => AreEqual(pp, propertyPathToMerge)) == null) { existingKey.PropertyPaths().Add(propertyPathToMerge); } } }
private void FinishRelation(QVTRelations.RelationalTransformation transformation, EnAr.Element relationElement) { // We use the existing Relation object QVTRelations.IRelation relation = FindRelation(transformation, relationElement.Name); // We look for the tag "where" string whereCode = explorer.GetTaggedValue(relationElement, "Where"); if (!string.IsNullOrWhiteSpace(whereCode)) { relation.Where = ConstructWhenOrWherePattern(relation, whereCode); } // We look for the tag "when" string whenCode = explorer.GetTaggedValue(relationElement, "When"); if (!string.IsNullOrWhiteSpace(whenCode)) { relation.When = ConstructWhenOrWherePattern(relation, whenCode); } // We look for the tag 'qvtKey' string qvtKeyString = explorer.GetTaggedValue(relationElement, "qvtKey"); if (!string.IsNullOrWhiteSpace(qvtKeyString)) { relationsWithKeys.Add(relation); ISet <EMOF.IClass> classes = FindAllClassesUsedInRelation(relation); IList <QvtKeyParserResult> parsed = QvtKeyParser.Parse(qvtKeyString); foreach (QvtKeyParserResult keyParserResult in parsed) { QVTRelations.IKey key = ConstructKey(classes, keyParserResult); QVTRelations.IKey existingKey = relation.Keys().FirstOrDefault(k => k.Identifies == key.Identifies); if (existingKey == null) { relation.Keys().Add(key); } else { MergeKeyInto(existingKey, key); } } } }
private QVTRelations.IRelationalTransformation ConstructRelationalTransformation(EnAr.Element transformationElement) { // We create a Transformation object QVTRelations.RelationalTransformation transformation = new QVTRelations.RelationalTransformation { Name = transformationElement.Name, }; // We first find the "Functions" class that contains the functions of the transformation EnAr.Element functionsClass = explorer.GetChildrenElementsWithType(transformationElement, "class").FirstOrDefault(e => e.Stereotype.IsNullOrEmpty()); if (functionsClass != null) { // For each method, we create a Function in the QVT transforamtion foreach (EnAr.Method method in functionsClass.Methods.OfType <EnAr.Method>()) { ConstructFunction(transformation, method); } } // We browse the children EA elements with the stereotype "qvtRelation" IList <EnAr.Element> relationsElements = explorer.GetChildrenElementsWithTypeAndStereotype(transformationElement, "class", "qvtRelation"); // First pass: we create the basic relations (to manage relation calls later) foreach (EnAr.Element relationElement in relationsElements) { ConstructBasicRelation(transformation, relationElement); } // Second pass, we finish the relations (with relation calls) foreach (EnAr.Element relationElement in relationsElements) { FinishRelation(transformation, relationElement); } // We look for the tag 'qvtKey' string qvtKeyString = explorer.GetTaggedValue(transformationElement, "qvtKey"); if (!string.IsNullOrWhiteSpace(qvtKeyString)) { ISet <EMOF.IClass> classes = FindAllClassesUsedInTransformation(transformation); IList <QvtKeyParserResult> parsed = QvtKeyParser.Parse(qvtKeyString); foreach (QvtKeyParserResult keyParserResult in parsed) { QVTRelations.IKey key = ConstructKey(classes, keyParserResult); QVTRelations.IKey existingKey = transformation.OwnedKey.FirstOrDefault(k => k.Identifies == key.Identifies); if (existingKey == null) { transformation.OwnedKey.Add(key); } else { MergeKeyInto(existingKey, key); } } } // We check if some relation-level keys should not be removed because subsumed by global keys foreach (QVTRelations.IRelation relationWithKeys in relationsWithKeys) { foreach (QVTRelations.IKey key in relationWithKeys.Keys().ToList()) { QVTRelations.IKey superKey = transformation.OwnedKey.FirstOrDefault(k => Subsumes(k, key)); if (superKey != null) { relationWithKeys.Keys().Remove(key); } } } //TODO QVT Query Functions owned by the transformation? return(transformation); }