private EMOF.IClass ConstructClass(EnAr.Element classElement) { // We create a EMOF.Class EMOF.IClass clazz = new EMOF.Class() { IsAbstract = classElement.Abstract.ToLower() == "true", Name = classElement.Name }; elementToType.Add(classElement, clazz); // We browse the attributes of the EMOF.Class element (~= ecore attributes) foreach (EnAr.Attribute attribute in explorer.GetAttributes(classElement)) { EMOF.IProperty property = ConstructProperty(attribute); property.Class = clazz; clazz.OwnedAttribute.Add(property); } // We browse the connectors (~= ecore references + inheritance links) foreach (EnAr.Connector connector in explorer.GetConnectorsWithSource(classElement)) { EnAr.Element targetElement = explorer.GetTargetElement(connector); if (targetElement.Type.ToLower() == "class") { EMOF.IClass targetType = ConstructType(targetElement) as EMOF.Class; if (targetType != null) { // Case super type if (connector.Type.ToLower() == "generalization") { clazz.SuperClass.Add(targetType); } // Case reference(s) else { EMOF.IProperty prop1 = ConstructProperty(clazz, targetType, connector.ClientEnd, connector.SupplierEnd); EMOF.IProperty prop2 = ConstructProperty(targetType, clazz, connector.SupplierEnd, connector.ClientEnd); if (prop1 != null && prop2 != null) { prop1.Opposite = prop2; prop2.Opposite = prop1; } } } } } // And finally the methods foreach (EnAr.Method method in explorer.GetMethods(classElement)) { EMOF.IOperation operation = ConstructOperation(method); clazz.OwnedOperation.Add(operation); operation.Class = clazz; } return(clazz); }
private static QVTRelations.IKey ConstructKey(ISet <EMOF.IClass> reachableClasses, QvtKeyParserResult keyParserResult) { EMOF.IClass clazz = reachableClasses.Single(c => c.Name == keyParserResult.ClassName); QVTRelations.IKey key = new QVTRelations.Key { Identifies = clazz }; foreach (IList <string> propertyPathList in keyParserResult.NavigatedProperties) { // Case multiple navigated properties, we use our QVT extension "PropertyPaths" if (propertyPathList.Count > 1) { PropertyPath propertyPath = new PropertyPath(); EMOF.IClass currentClass = clazz; foreach (string propertyName in propertyPathList) { if (currentClass == null) { throw new InvalidQVTRelationsModelException("Wrong key somewhere, impossible to reach: \'" + propertyName + "\'"); } EMOF.IProperty nextProperty = currentClass.OwnedAttribute.Single(p => p.Name == propertyName); if (nextProperty.isMany()) { throw new InvalidQVTRelationsModelException("Wrong key somewhere, cannot use a collection as part of key for now: \'" + propertyName + "\'"); } propertyPath.Properties.Add(nextProperty); currentClass = nextProperty.Type as EMOF.IClass; } key.PropertyPaths().Add(propertyPath); } // Else, we fill the regular "part" of the key else { EMOF.IProperty property = clazz.OwnedAttribute.Single(p => p.Name == propertyPathList.Single()); if (property.isMany()) { throw new InvalidQVTRelationsModelException("Wrong key somewhere, cannot use a collection as part of key for now: \'" + property.Name + "\'"); } key.Part.Add(property); } } return(key); }
private static bool AreEqual(PropertyPath p1, PropertyPath p2) { if (p1.Properties.Count == p2.Properties.Count) { foreach (EMOF.IProperty p1Property in p1.Properties) { EMOF.IProperty p2Property = p2.Properties[p1.Properties.IndexOf(p1Property)]; if (p1Property != p2Property) { return(false); } } } else { return(false); } return(true); }
private QVTTemplate.IPropertyTemplateItem ConstructPropertyTemplateItem(QVTRelations.IRelation relation, QVTRelations.IDomainPattern domainPattern, QVTTemplate.IObjectTemplateExp objectTemplateExp, RunStateField runStateField) { ISet <EMOF.IProperty> atts = objectTemplateExp.ReferredClass.GetAllInheritedAttributes(); EMOF.IProperty property = atts.Single(p => string.Equals(p.Name, runStateField.Variable, StringComparison.CurrentCultureIgnoreCase)); QVTTemplate.IPropertyTemplateItem propertyTemplateItem = null; if (property != null) { EssentialOCL.IOclExpression expression = ConstructOCLExpression(relation, runStateField.Value, domainPattern, property.Type); propertyTemplateItem = new QVTTemplate.PropertyTemplateItem() { ReferredProperty = property, Value = expression, IsOpposite = false, // TODO? ObjContainer = objectTemplateExp }; } return(propertyTemplateItem); }
private QVTTemplate.IPropertyTemplateItem ConstructPropertyTemplateItem(QVTRelations.IRelation relation, QVTRelations.IDomainPattern domainPattern, QVTTemplate.IObjectTemplateExp objectTemplateExp, EnAr.Connector connector, EnAr.ConnectorEnd connectorEnd, EnAr.Element linkedElement, ISet <EnAr.Connector> visitedConnectors) { EssentialOCL.IOclExpression value; EMOF.IType type; QVTTemplate.IObjectTemplateExp targetObjectTemplateExp; ISet <EnAr.Connector> realVisitedConnectors = visitedConnectors ?? new HashSet <EnAr.Connector>(); ISet <EnAr.Connector> realVisitedConnectorsPropagated = new HashSet <EnAr.Connector>(realVisitedConnectors); realVisitedConnectorsPropagated.Add(connector); // Case cycle among object templates: simple variable expression if (objectElementToObjectTemplate.ContainsKey(linkedElement)) { targetObjectTemplateExp = objectElementToObjectTemplate[linkedElement]; EssentialOCL.IVariable existingVariable = targetObjectTemplateExp.BindsTo; value = new EssentialOCL.VariableExp() { ReferredVariable = existingVariable }; type = existingVariable.Type; } // Case no cycle; recursive creation of object template else { targetObjectTemplateExp = ConstructObjectTemplateExp(relation, domainPattern, linkedElement, realVisitedConnectorsPropagated); value = targetObjectTemplateExp; type = ((QVTTemplate.IObjectTemplateExp)value).BindsTo.Type; } EMOF.IProperty property = null; // If the connector end has a role, we use it to find the corresponding EMOF property if (!string.IsNullOrWhiteSpace(connectorEnd.Role)) { property = objectTemplateExp.ReferredClass.GetAllInheritedAttributes().Single(p => p.Name == connectorEnd.Role); } // If the connector end has no role (due to the else) // AND if we haven't visited the connector yet // AND if the connector has no roles whatsoever, we try to guess the type else if (!realVisitedConnectors.Contains(connector) && connector.ClientEnd.Role.IsNullOrEmpty() && connector.SupplierEnd.Role.IsNullOrEmpty()) { IList <EMOF.IProperty> candidateProperties = objectTemplateExp.ReferredClass.GetAllInheritedAttributes().Where(p => (p.Type as EMOF.IClass)?.GetAllSubTypes().Contains(type) ?? p.Type == type).ToList(); if (candidateProperties.Count == 0) { throw new InvalidQVTRelationsModelException("Relation " + relation.Name + ", invalid property connector between " + objectTemplateExp.BindsTo.Name + " and " + targetObjectTemplateExp.BindsTo.Name + ", no possible property", connector); } if (candidateProperties.Count > 1) { throw new InvalidQVTRelationsModelException("Relation " + relation.Name + ", ambiguous property connector between " + objectTemplateExp.BindsTo.Name + " and " + targetObjectTemplateExp.BindsTo.Name + ", cannot choose a property between the following: [" + string.Join(";", candidateProperties.Select(p => p.Name)) + "]", connector); } property = candidateProperties.Single(); } QVTTemplate.PropertyTemplateItem propertyTemplateItem = null; if (property != null) { propertyTemplateItem = new QVTTemplate.PropertyTemplateItem() { ReferredProperty = property, Value = value, IsOpposite = false, // TODO? ObjContainer = objectTemplateExp }; } return(propertyTemplateItem); }