private List<RelationshipsOptimization> GetOptimizationsRefRelationshipsSameLevel(DomainClass start, List<DomainClass> alreadyProcessedBaseClasses)
        {
            List<RelationshipsOptimization> opt = new List<RelationshipsOptimization>();
            Dictionary<object, List<DomainClass>> embeddedClasses = new Dictionary<object, List<DomainClass>>();
            Dictionary<object, Dictionary<object, List<DomainRelationship>>> refClasses = new Dictionary<object, Dictionary<object, List<DomainRelationship>>>();

            // gather references for found embeddings
            foreach (DomainRole role in start.RolesPlayed)
                if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.EmbeddingRelationship)
                {
                    DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                    if (target == null)
                        continue;

                    object bClass = "NULL";
                    if (target.BaseClass != null)
                        bClass = target.BaseClass;

                    if (!embeddedClasses.ContainsKey(bClass))
                        embeddedClasses.Add(bClass, new List<DomainClass>());
                    embeddedClasses[bClass].Add(target);

                    foreach(DomainClass dClass in target.DerivedClasses)
                    {
                        object bClass2 = "NULL";
                        if (dClass.BaseClass != null)
                            bClass2 = dClass.BaseClass;

                        if (!embeddedClasses.ContainsKey(bClass2))
                            embeddedClasses.Add(bClass2, new List<DomainClass>());
                        embeddedClasses[bClass2].Add(dClass);
                    }
                }

            // gather references for found embeddings
            foreach(object key in embeddedClasses.Keys)
                if( embeddedClasses[key].Count > 1 )
                {
                    refClasses.Add(key, new Dictionary<object, List<DomainRelationship>>());

                    foreach (DomainClass c in embeddedClasses[key])
                        foreach (DomainRole role in c.RolesPlayed)
                            if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.ReferenceRelationship)
                            {
                                DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                                if (target == null)
                                    continue;
                                if (!embeddedClasses[key].Contains(target))
                                    continue;

                                object bClass = "NULL";
                                if (target.BaseClass != null)
                                    bClass = target.BaseClass;

                                if (!refClasses[key].ContainsKey(bClass))
                                    refClasses[key].Add(bClass, new List<DomainRelationship>());
                                refClasses[key][bClass].Add(role.Relationship);
                            }
                }

            // continue with children
            foreach (DomainRole role in start.RolesPlayed)
                if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.EmbeddingRelationship)
                {
                    if (!(role.Relationship.Source.RolePlayer is DomainClass))
                        continue;
                    if (!(role.Relationship.Target.RolePlayer is DomainClass))
                        continue;

                    DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                    if (target == null)
                        continue;
                    if (!alreadyProcessedBaseClasses.Contains(target))
                    {
                        alreadyProcessedBaseClasses.Add(target);
                        opt.AddRange(GetOptimizationsRefRelationshipsSameLevel(target, alreadyProcessedBaseClasses));
                    }
                }

            // Create opt
            if(refClasses.Keys.Count >0 )
                foreach(object key in refClasses.Keys)
                    if (refClasses[key].Count > 0)
                    {
                        foreach(object key2 in refClasses[key].Keys)
                            if (refClasses[key][key2].Count > 1)
                            {
                                // create optimization 
                                RelationshipsReferencesBetweenBaseClassesOptimization rOpt = new RelationshipsReferencesBetweenBaseClassesOptimization(this.MetaModel, this.ModelContext);
                                rOpt.Title = "Reference Relationship Optimization";
                                rOpt.Description = "Existing references are replaces with one reference. WARNING: This might extend/restrict existing constraints.";

                                if (key != key2)
                                    continue;

                                if (key is DomainClass)
                                    rOpt.BaseClass = key as DomainClass;

                                if (key2 is DomainClass)
                                    rOpt.BaseClassTarget = key2 as DomainClass;

                                // add classes and relationships
                                foreach (DomainRelationship r in refClasses[key][key2])
                                {
                                    if (!rOpt.InvolvedClasses.Contains(r.Source.RolePlayer as DomainClass))
                                        rOpt.InvolvedClasses.Add(r.Source.RolePlayer as DomainClass);
                                    if (!rOpt.InvolvedClasses.Contains(r.Target.RolePlayer as DomainClass))
                                        rOpt.InvolvedClasses.Add(r.Target.RolePlayer as DomainClass);
                                    if (!rOpt.InvolvedRelationships.Contains(r))
                                        rOpt.InvolvedRelationships.Add(r);
                                }

                                if (rOpt.BaseClass is DomainClass)
                                    if (!rOpt.InvolvedClasses.Contains(rOpt.BaseClass))
                                        rOpt.InvolvedClasses.Add(rOpt.BaseClass);
                                if (rOpt.BaseClassTarget is DomainClass)
                                    if (!rOpt.InvolvedClasses.Contains(rOpt.BaseClassTarget))
                                        rOpt.InvolvedClasses.Add(rOpt.BaseClassTarget);

                                opt.Add(rOpt);
                            }
                    }

            return opt;
        }
Ejemplo n.º 2
0
        private List <RelationshipsOptimization> GetOptimizationsRefRelationshipsSameLevel(DomainClass start, List <DomainClass> alreadyProcessedBaseClasses)
        {
            List <RelationshipsOptimization>         opt             = new List <RelationshipsOptimization>();
            Dictionary <object, List <DomainClass> > embeddedClasses = new Dictionary <object, List <DomainClass> >();
            Dictionary <object, Dictionary <object, List <DomainRelationship> > > refClasses = new Dictionary <object, Dictionary <object, List <DomainRelationship> > >();

            // gather references for found embeddings
            foreach (DomainRole role in start.RolesPlayed)
            {
                if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.EmbeddingRelationship)
                {
                    DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                    if (target == null)
                    {
                        continue;
                    }

                    object bClass = "NULL";
                    if (target.BaseClass != null)
                    {
                        bClass = target.BaseClass;
                    }

                    if (!embeddedClasses.ContainsKey(bClass))
                    {
                        embeddedClasses.Add(bClass, new List <DomainClass>());
                    }
                    embeddedClasses[bClass].Add(target);

                    foreach (DomainClass dClass in target.DerivedClasses)
                    {
                        object bClass2 = "NULL";
                        if (dClass.BaseClass != null)
                        {
                            bClass2 = dClass.BaseClass;
                        }

                        if (!embeddedClasses.ContainsKey(bClass2))
                        {
                            embeddedClasses.Add(bClass2, new List <DomainClass>());
                        }
                        embeddedClasses[bClass2].Add(dClass);
                    }
                }
            }

            // gather references for found embeddings
            foreach (object key in embeddedClasses.Keys)
            {
                if (embeddedClasses[key].Count > 1)
                {
                    refClasses.Add(key, new Dictionary <object, List <DomainRelationship> >());

                    foreach (DomainClass c in embeddedClasses[key])
                    {
                        foreach (DomainRole role in c.RolesPlayed)
                        {
                            if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.ReferenceRelationship)
                            {
                                DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                                if (target == null)
                                {
                                    continue;
                                }
                                if (!embeddedClasses[key].Contains(target))
                                {
                                    continue;
                                }

                                object bClass = "NULL";
                                if (target.BaseClass != null)
                                {
                                    bClass = target.BaseClass;
                                }

                                if (!refClasses[key].ContainsKey(bClass))
                                {
                                    refClasses[key].Add(bClass, new List <DomainRelationship>());
                                }
                                refClasses[key][bClass].Add(role.Relationship);
                            }
                        }
                    }
                }
            }

            // continue with children
            foreach (DomainRole role in start.RolesPlayed)
            {
                if (role.Relationship.Source == role && role.Relationship is Tum.PDE.LanguageDSL.EmbeddingRelationship)
                {
                    if (!(role.Relationship.Source.RolePlayer is DomainClass))
                    {
                        continue;
                    }
                    if (!(role.Relationship.Target.RolePlayer is DomainClass))
                    {
                        continue;
                    }

                    DomainClass target = role.Relationship.Target.RolePlayer as DomainClass;
                    if (target == null)
                    {
                        continue;
                    }
                    if (!alreadyProcessedBaseClasses.Contains(target))
                    {
                        alreadyProcessedBaseClasses.Add(target);
                        opt.AddRange(GetOptimizationsRefRelationshipsSameLevel(target, alreadyProcessedBaseClasses));
                    }
                }
            }

            // Create opt
            if (refClasses.Keys.Count > 0)
            {
                foreach (object key in refClasses.Keys)
                {
                    if (refClasses[key].Count > 0)
                    {
                        foreach (object key2 in refClasses[key].Keys)
                        {
                            if (refClasses[key][key2].Count > 1)
                            {
                                // create optimization
                                RelationshipsReferencesBetweenBaseClassesOptimization rOpt = new RelationshipsReferencesBetweenBaseClassesOptimization(this.MetaModel, this.ModelContext);
                                rOpt.Title       = "Reference Relationship Optimization";
                                rOpt.Description = "Existing references are replaces with one reference. WARNING: This might extend/restrict existing constraints.";

                                if (key != key2)
                                {
                                    continue;
                                }

                                if (key is DomainClass)
                                {
                                    rOpt.BaseClass = key as DomainClass;
                                }

                                if (key2 is DomainClass)
                                {
                                    rOpt.BaseClassTarget = key2 as DomainClass;
                                }

                                // add classes and relationships
                                foreach (DomainRelationship r in refClasses[key][key2])
                                {
                                    if (!rOpt.InvolvedClasses.Contains(r.Source.RolePlayer as DomainClass))
                                    {
                                        rOpt.InvolvedClasses.Add(r.Source.RolePlayer as DomainClass);
                                    }
                                    if (!rOpt.InvolvedClasses.Contains(r.Target.RolePlayer as DomainClass))
                                    {
                                        rOpt.InvolvedClasses.Add(r.Target.RolePlayer as DomainClass);
                                    }
                                    if (!rOpt.InvolvedRelationships.Contains(r))
                                    {
                                        rOpt.InvolvedRelationships.Add(r);
                                    }
                                }

                                if (rOpt.BaseClass is DomainClass)
                                {
                                    if (!rOpt.InvolvedClasses.Contains(rOpt.BaseClass))
                                    {
                                        rOpt.InvolvedClasses.Add(rOpt.BaseClass);
                                    }
                                }
                                if (rOpt.BaseClassTarget is DomainClass)
                                {
                                    if (!rOpt.InvolvedClasses.Contains(rOpt.BaseClassTarget))
                                    {
                                        rOpt.InvolvedClasses.Add(rOpt.BaseClassTarget);
                                    }
                                }

                                opt.Add(rOpt);
                            }
                        }
                    }
                }
            }

            return(opt);
        }