private void BuildModelNamespaceAssociations(XmlNode elementsExtension, string modelFile) { if (elementsExtension == null) { throw new ArgumentNullException("elementsExtension"); } foreach (XmlNode connectorChildNode in elementsExtension.SelectNodes(NodeAssociations, _currentNsManager)) { if (connectorChildNode != null) { XmlNode associationNode = connectorChildNode.ParentNode; XmlNode sourceNode = associationNode.SelectSingleNode(NodeSource, _currentNsManager); XmlNode targetNode = associationNode.SelectSingleNode(NodeTarget, _currentNsManager); string name = associationNode.SelectSingleNode(NodeLabels, _currentNsManager).Attributes[PropertyAssociationName].Value; string columnName = null; XmlNode columnNameNode = associationNode.SelectSingleNode(NodeTagColumnName, _currentNsManager); if (columnNameNode != null) { columnName = columnNameNode.Attributes[PropertyValue].Value; } XmlAttribute associationCodeAttribute = associationNode.SelectSingleNode(NodeStyle, _currentNsManager).Attributes[PropertyValue]; string code = (associationCodeAttribute != null) ? _regexAssociationName.Replace(associationCodeAttribute.Value, "$1") : string.Empty; XmlAttribute commentAttribute = associationNode.SelectSingleNode(NodeComment, _currentNsManager).Attributes[PropertyValue]; string comment = (commentAttribute == null) ? null : commentAttribute.Value; string multiplicitySource = sourceNode.SelectSingleNode(NodeType, _currentNsManager).Attributes[PropertyMultiplicity].Value; if ("1".Equals(multiplicitySource)) { multiplicitySource = Multiplicity11; } string multiplicityTarget = targetNode.SelectSingleNode(NodeType, _currentNsManager).Attributes[PropertyMultiplicity].Value; if ("1".Equals(multiplicityTarget)) { multiplicityTarget = Multiplicity11; } XmlAttribute roleSourceAttribute = sourceNode.SelectSingleNode(NodeRole, _currentNsManager).Attributes[PropertyName]; string roleSourceName = (roleSourceAttribute == null) ? string.Empty : roleSourceAttribute.Value; XmlAttribute roleTargetAttribute = targetNode.SelectSingleNode(NodeRole, _currentNsManager).Attributes[PropertyName]; string roleTargetName = (roleTargetAttribute == null) ? string.Empty : roleTargetAttribute.Value; ModelClass[] classAssociationTab; try { classAssociationTab = GetModelClassAssociation(associationNode, modelFile); } catch (Exception ex) { throw new NotSupportedException( string.Format( CultureInfo.CurrentCulture, @"Impossible de retrouver les classes de l'association suivante : [Code]:{0}, [Nom]:{1}. Vérifier que la classe avec la multiplicité la plus faible est bien définie avant l'autre classe. L'ordre de parsing des modèles est défini dans Build\class_generator.conf.", code, name), ex); } ModelClass classSource = classAssociationTab[0]; ModelClass classTarget = classAssociationTab[1]; string typeAssociation = associationNode.SelectSingleNode(NodeProperties, _currentNsManager).Attributes[PropertyEAType].Value; bool isTargetContientSource = AssociationComposition.Equals(sourceNode.SelectSingleNode(NodeType, _currentNsManager).Attributes[PropertyAggregation].Value); bool isSourceContientTarget = AssociationComposition.Equals(targetNode.SelectSingleNode(NodeType, _currentNsManager).Attributes[PropertyAggregation].Value); if (multiplicitySource != Multiplicity01 && multiplicitySource != Multiplicity11 && multiplicitySource != Multiplicty0N && multiplicitySource != Multiplicty1N) { RegisterError(Category.Error, "La multiplicité " + multiplicitySource + " du lien [" + code + "] entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] n'est pas gérée."); continue; } if (multiplicityTarget != Multiplicity01 && multiplicityTarget != Multiplicity11 && multiplicityTarget != Multiplicty0N && multiplicityTarget != Multiplicty1N) { RegisterError(Category.Error, "La multiplicité " + multiplicityTarget + " du lien [" + code + "] entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] n'est pas gérée."); continue; } bool multiplicityOk = false; if (multiplicitySource == Multiplicty0N && (multiplicityTarget == Multiplicity01 || multiplicityTarget == Multiplicity11 || multiplicityTarget == Multiplicty0N)) { multiplicityOk = true; } if (multiplicityTarget == Multiplicty0N && (multiplicitySource == Multiplicity01 || multiplicitySource == Multiplicity11 || multiplicitySource == Multiplicty0N)) { multiplicityOk = true; } if (!multiplicityOk && classTarget.IsTable && classSource.IsTable) { RegisterError(Category.Error, "L'association [" + code + "] (" + multiplicitySource + "/" + multiplicityTarget + ") entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] n'est pas gérée."); continue; } if (EATypeAssociation.Equals(typeAssociation) && classSource.Stereotype == StereotypeStatique && multiplicitySource == Multiplicty0N && classTarget.Stereotype != StereotypeStatique) { RegisterError(Category.Error, "L'association [" + code + "] (" + multiplicitySource + "/" + multiplicityTarget + ") entre les classes [" + classSource.Name + "] statique et [" + classTarget.Name + "] n'est pas gérée."); continue; } if (classTarget.Stereotype == StereotypeStatique && multiplicityTarget == Multiplicty0N && !(multiplicitySource == Multiplicty0N) && classSource.Stereotype != StereotypeStatique) { RegisterError(Category.Error, "L'association [" + code + "] (" + multiplicitySource + "/" + multiplicityTarget + ") entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] statique n'est pas gérée."); continue; } if (classSource.Stereotype == StereotypeReference && multiplicitySource == Multiplicty0N && classTarget.Stereotype != StereotypeStatique && classTarget.Stereotype != StereotypeReference && classTarget.IsTable) { RegisterError(Category.Error, "L'association [" + code + "] (" + multiplicitySource + "/" + multiplicityTarget + ") entre les classes [" + classSource.Name + "] reference et [" + classTarget.Name + "] n'est pas gérée."); continue; } if (classTarget.Stereotype == StereotypeReference && multiplicityTarget == Multiplicty0N && !(multiplicitySource == Multiplicty0N) && classSource.Stereotype != StereotypeStatique && classSource.Stereotype != StereotypeReference && !classSource.IgnoreReferenceToReference) { RegisterError(Category.Error, "L'association [" + code + "] (" + multiplicitySource + "/" + multiplicityTarget + ") entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] reference n'est pas gérée."); continue; } if (string.IsNullOrEmpty(name)) { RegisterError(Category.Error, "L'association [" + code + "] ne porte pas le libellé de la propriété associée à la clef étrangère."); continue; } bool isComposition = !string.IsNullOrEmpty(typeAssociation) && EATypeAggregation.Equals(typeAssociation); if (isComposition) { // Si composition il faut traiter la cardinalité target et l'ajouter dans la classe source ou inversement. ModelProperty property; if (isTargetContientSource) { property = ParserHelper.BuildClassCompositionProperty(classSource, multiplicitySource, name, code, string.IsNullOrEmpty(comment) ? name : comment); property.Class = classTarget; classTarget.AddProperty(property); classTarget.AddUsing(classSource.Namespace); } else if (isSourceContientTarget) { property = ParserHelper.BuildClassCompositionProperty(classTarget, multiplicityTarget, name, code, string.IsNullOrEmpty(comment) ? name : comment); property.Class = classSource; classSource.AddProperty(property); classSource.AddUsing(classTarget.Namespace); } else { RegisterError(Category.Error, "La composition [" + code + "] entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] doit définir l'élément qui contient l'autre."); continue; } IndexAssociation(property, comment); } else { bool treated = false; if (Multiplicity01.Equals(multiplicityTarget) || Multiplicity11.Equals(multiplicityTarget)) { // On ajoute la clé primaire de la classe target dans la classe source ModelProperty property = ParserHelper.BuildClassAssociationProperty(classTarget, classSource, multiplicityTarget, roleSourceName, name, columnName); if (classSource.DataContract.IsPersistent && !classTarget.DataContract.IsPersistent) { RegisterError(Category.Error, "L'association [" + code + "] de multiplicité 0..1/1..1 entre la classe persistente [" + classSource.Name + "] et la classe non persistente [" + classTarget.Name + "] n'est pas possible."); continue; } property.Class = classSource; classSource.AddProperty(property); IndexAssociation(property, comment); treated = true; } if (Multiplicity01.Equals(multiplicitySource) || Multiplicity11.Equals(multiplicitySource)) { // On ajoute la clé primaire de la classe source dans la classe target ModelProperty property = ParserHelper.BuildClassAssociationProperty(classSource, classTarget, multiplicitySource, roleTargetName, name, columnName); if (classTarget.DataContract.IsPersistent && !classSource.DataContract.IsPersistent) { RegisterError(Category.Error, "L'association [" + code + "] de multiplicité 0..1/1..1 entre la classe persistente [" + classTarget.Name + "] et la classe non persistente [" + classSource.Name + "] n'est pas possible."); continue; } property.Class = classTarget; classTarget.AddProperty(property); IndexAssociation(property, comment); treated = true; } if (Multiplicty0N.Equals(multiplicitySource) && Multiplicty0N.Equals(multiplicityTarget)) { // On ajoute une liste de la clé primaire de la classe target dans la classe source if (classSource.DataContract.IsPersistent) { RegisterError(Category.Error, "L'association [" + code + "] de multiplicité 0..N/0..N entre la classe persistente [" + classSource.Name + "] et la classe [" + classTarget.Name + "] n'est pas possible."); continue; } ModelProperty property = ParserHelper.BuildClassAssociationListProperty(classTarget, classSource, roleSourceName, name); property.Class = classSource; classSource.AddProperty(property); treated = true; } if (!treated) { RegisterError(Category.Bug, "Le lien d'association [" + code + "] entre les classes [" + classSource.Name + "] et [" + classTarget.Name + "] nommé " + name + " (code=" + code + ") n'est pas géré actuellement."); } } } } }