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."); } } } } }
private void BuildClassProperties(ModelClass classe, XmlNode classNode, XmlNode classExtensionNode, string modelFile) { ICollection <string> pkRefList = GetClassPrimaryKeysIdList(classExtensionNode); XmlNode attributesNode = classExtensionNode.SelectSingleNode(NodeAttributes, _currentNsManager); if (attributesNode != null) { foreach (XmlNode propertyNode in attributesNode.ChildNodes) { string propertyId = propertyNode.Attributes[PropertyIdRef].Value; string styleEx = propertyNode.SelectSingleNode(PropertyStyleEx, _currentNsManager).Attributes[PropertyValue].Value; bool isPersistent = "0".Equals(_regexPropertyPersistance.Replace(styleEx, "$1")); string multiplicityLower = propertyNode.SelectSingleNode(NodeBounds, _currentNsManager).Attributes[PropertyMultiplicityLower].Value; string multiplicityUpper = propertyNode.SelectSingleNode(NodeBounds, _currentNsManager).Attributes[PropertyMultiplicityUpper].Value; if ("-1".Equals(multiplicityUpper)) { multiplicityUpper = "*"; } string multiplicity = multiplicityLower + ".." + multiplicityUpper; ModelDomain domain = GetDomainByCode(propertyNode.SelectSingleNode(NodeProperties, _currentNsManager).Attributes[PropertyType].Value); XmlAttribute stereotypeAttribute = propertyNode.SelectSingleNode(NodeStereotype, _currentNsManager).Attributes[PropertyStereotype]; XmlNode uniqueNode = propertyNode.SelectSingleNode(NodeTagUnique, _currentNsManager); ModelProperty property = new ModelProperty() { Name = propertyNode.SelectSingleNode(NodeStyle, _currentNsManager).Attributes[PropertyValue].Value, Comment = propertyNode.SelectSingleNode(NodeComment, _currentNsManager).Attributes[PropertyValue].Value, IsPersistent = isPersistent, IsUnique = uniqueNode != null, DataType = domain.DataType, Stereotype = (stereotypeAttribute == null) ? string.Empty : stereotypeAttribute.Value, Class = classe, ModelFile = modelFile, DataDescription = new ModelDataDescription() { Libelle = propertyNode.Attributes[PropertyName].Value, Domain = domain, IsPrimaryKey = pkRefList.Contains(propertyId) } }; if (!ParserHelper.IsPrimitiveType(property.DataType)) { RegisterError(Category.Error, "Propriété " + classe.Name + "." + property.Name + " : le type de la propriété " + property.DataType + " n'est pas primitif, il faut utiliser les liens de composition."); continue; } string dataMemberName = string.Empty; if (property.IsPersistent) { if (property.DataDescription.IsPrimaryKey) { classe.Trigram = property.DataDescription.Libelle; } string columnName = null; XmlNode columnNameNode = propertyNode.SelectSingleNode(NodeTagColumnName, _currentNsManager); if (columnNameNode != null) { columnName = columnNameNode.Attributes[PropertyValue].Value; } if (string.IsNullOrEmpty(columnName)) { XmlNode columnTypeNode = propertyNode.SelectSingleNode(NodeTagColumnType, _currentNsManager); string columnType = string.Empty; if (columnTypeNode != null) { columnType = columnTypeNode.Attributes[PropertyValue].Value; } if (property.DataDescription.IsPrimaryKey) { columnName = columnType + classe.Name; } else { columnName = columnType + property.Name; } } dataMemberName = columnName; } property.DataMember = new ModelDataMember() { Name = dataMemberName, IsRequired = multiplicity != null && Multiplicity11.Equals(multiplicity) }; if (property.DataDescription.IsPrimaryKey || !string.IsNullOrEmpty(property.DataDescription.ReferenceType)) { property.DataDescription.Libelle = property.Name; } classe.AddProperty(property); if (!string.IsNullOrEmpty(property.Stereotype) && property.Stereotype != StereotypeDefaultProperty && property.Stereotype != StereotypePrimaryKey) { RegisterError(Category.Error, "Propriété " + classe.Name + "." + property.Name + " : seul les stéréotypes '" + StereotypeDefaultProperty + "' et '" + StereotypePrimaryKey + "' sont acceptés."); } } } }