Example #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.");
                        }
                    }
                }
            }
        }
Example #2
0
        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.");
                    }
                }
            }
        }