예제 #1
0
        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.");
                        }
                    }
                }
            }
        }